P1005 矩阵取数游戏
思路:可以用递归写法或者dp写法,但这道题会爆精度,__int128能过
先给出递归代码
1 #include<bits/stdc++.h> 2 #define in(x) x=read() 3 #define MAXN 81 4 #define k m-(R-L) 5 #define bll __int128 6 7 using namespace std; 8 9 inline int read() 10 { 11 int X=0,w=1; 12 char ch=getchar(); 13 while(ch<'0' || ch>'9') {if(ch=='-') w=-1;ch=getchar();} 14 while(ch>='0' && ch<='9') X=(X<<3)+(X<<1)+ch-'0',ch=getchar(); 15 return X*w; 16 } 17 18 int n,m; 19 int num[MAXN]; 20 bll ans,p[MAXN],f[MAXN][MAXN]; 21 22 bll dp(int L,int R)//记忆化搜索 23 { 24 if(f[L][R]!=-1) return f[L][R]; 25 if(R-L>=1) f[L][R]=max(num[L]*p[k]+dp(L+1,R),dp(L,R-1)+num[R]*p[k]); 26 else f[L][R]=num[L]*p[k]; 27 return f[L][R]; 28 } 29 30 void print(bll x) 31 { 32 if(!x) return; 33 if(x) print(x/10); 34 putchar(x%10+'0'); 35 } 36 37 int main() 38 { 39 in(n);in(m); 40 p[0]=1; 41 for(int i=1;i<=m;i++) p[i]=p[i-1]*2; 42 for(int i=1;i<=n;i++){ 43 for(int j=1;j<=m;j++) in(num[j]); 44 memset(f,-1,sizeof(f)); 45 ans+=dp(1,m); 46 } 47 if(!ans) printf("0"); 48 else print(ans); 49 return 0; 50 }
dp代码
1 #include <bits/stdc++.h> 2 3 using namespace std; 4 5 const int MAXN=81; 6 7 inline void input(__int128 &s) 8 { 9 s=0; 10 char c=' '; 11 while(c>'9'||c<'0') c=getchar(); 12 while(c>='0'&&c<='9') 13 { 14 s=s*10+c-'0'; 15 c=getchar(); 16 } 17 } 18 19 inline void output(__int128 x) 20 { 21 if(x>9) 22 output(x/10); 23 putchar(x%10+'0'); 24 } 25 26 int n, m; 27 __int128 game[MAXN][MAXN]; 28 29 __int128 f[MAXN][MAXN]; 30 __int128 solve(__int128 a[]) 31 { 32 memset(f,0,sizeof(f)); 33 for(int len=0;len<=m;++len) 34 for(int i=1;i+len<=m;++i) 35 f[i][i+len]=max(2*f[i+1][i+len]+2*a[i],2*f[i][i+len-1]+2*a[i+len]); 36 return f[1][m]; 37 } 38 39 __int128 ans=0; 40 int main() 41 { 42 cin>>n>>m; 43 for(int i=1;i<=n;i++) 44 for(int j=1;j<=m;j++) 45 input(game[i][j]); 46 for(int i=1;i<=n;i++) 47 ans+=solve(game[i]); 48 output(ans); 49 return 0; 50 }
(代码来自他人)

浙公网安备 33010602011771号