題目描述
帥帥經常跟同學玩一個矩陣取數游戲:對于一個給定的 n \times mn×m 的矩陣,矩陣中的每個元素 a_{i,j}a
i,j
?
均為非負整數,游戲規則如下:
每次取數時須從每行各取走一個元素,共 nn 個,經過 mm 次后取完矩陣內所有元素;
每次取走的各個元素只能是該元素所在行的行首或行尾;
每次取數都有一個得分值,為每行取數的得分之和,每行取數的得分 = 被取走的元素值 \times 2^i×2
i
,其中 ii 表示第 ii 次取數(從 11 開始編號);
游戲結束總得分為 mm 次取數得分之和,
帥帥想請你幫忙寫一個程式,對于任意矩陣,可以求出取數后的最大得分,
輸入格式
輸入檔案包括 n+1n+1 行:
第一行為兩個用空格隔開的整數 nn 和 mm,
第 2\backsim n+12∽n+1 行為 n \times mn×m 矩陣,其中每行有 mm 個用單個空格隔開的非負整數,
輸出格式
輸出檔案僅包含11行,為一個整數,即輸入矩陣取數后的最大得分,
輸入輸出樣例
輸入 #1復制
2 3
1 2 3
3 4 2
輸出 #1復制
82
說明/提示
NOIP 2007 提高第三題,
資料范圍:
60%60% 的資料滿足:1\le n,m\le 301≤n,m≤30,答案不超過 10^{16}10
16
,
100%100% 的資料滿足:1\le n,m\le 801≤n,m≤80,0\le a_{i,j}\le10000≤a
i,j
?
≤1000,
#include<bits/stdc++.h>
#define max(x,y) (x>y?x:y)
using namespace std;
__int128 f[105][105],ans;//_int128 (高精,比int多一位)(int:127)
int n,m,len,Ans[105],mp[105][105],a[105];
inline int read()
{
int kr=1,xs=0;
char ls;
ls=getchar();
while(!isdigit(ls))
{
if(ls=='-')
kr=-1;
ls=getchar();
}
while(isdigit(ls))
{
xs=(xs<<1)+(xs<<3)+(ls^48);
ls=getchar();
}
return xs*kr;
}
int main()
{
n=read();m=read();
for(int i=1;i<=n;++i)
for(int j=1;j<=m;++j)
mp[i][j]=read();
for(int j=1;j<=n;++j)
{
memset(f,0,sizeof(f));
for(int i=1;i<=m;++i)a[i]=mp[j][i];
for(int len=0;len<=m;++len)
{
for(int i=1;i<=m-len;++i)
{
f[i][i+len]=max((a[i]<<1)+(f[i+1][i+len]<<1),(f[i][i+len-1]<<1)+(a[i+len]<<1));
}
}
ans+=f[1][m];
}
while(ans)
{
Ans[++len]=ans%10;
ans/=10;
}
if(len==0)return printf("0"),0;
for(int i=len;i>=1;--i)
printf("%d",Ans[i]);
return 0;
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/148469.html
標籤:C++
上一篇:P1004 方格取數
