矩阵dp
这里是矩阵dp,不是矩阵乘法优化dp。
矩阵上的dp好像也没什么特殊的?大概有一个套路就是从上向下,从左向右进行dp吧。
首先第一道题好像不是矩阵dp...
1005 矩阵取数游戏:https://www.luogu.org/problemnew/show/P1005
题意概述:在一个矩阵里面取数,每次从每行的左或右取一个数,并乘以$2^i$,$i$是取数的次数。直到取完为止,求最大得分。
看起来是道非常复杂的矩阵dp题,理性分析一下可以发现每一行之间并没有什么关系,所以分行做完以后再加起来就可以啦。那么在每一行内怎么做呢?像区间dp一样,用$dp[i][j]$表示取到剩下区间$[i][j]$时的最大得分。
然后再加上高精...
1 # include <cstdio> 2 # include <iostream> 3 # include <cstring> 4 # define R register int 5 6 using namespace std; 7 8 int n,m,j; 9 int len,a[81][81]; 10 int dp[81][81][1000]; 11 int P[81][100],ansc[81][1000],ans[1000]; 12 int t[1000]; 13 14 void add (int *a,int *b) 15 { 16 len=max(a[0],b[0])+2; 17 for (R i=1;i<=len;++i) 18 { 19 a[i]+=b[i]; 20 a[i+1]+=a[i]/10; 21 a[i]%=10; 22 } 23 while (a[len]==0&&len) len--; 24 a[0]=len; 25 } 26 27 void M (int *a,int *b) 28 { 29 if(a[0]>b[0]) return ; 30 if(b[0]>a[0]) 31 { 32 len=b[0]; 33 for (R i=0;i<=len;++i) 34 a[i]=b[i]; 35 return ; 36 } 37 len=a[0]; 38 for (R i=len;i>=1;--i) 39 { 40 if(a[i]>b[i]) return ; 41 if(a[i]==b[i]) continue; 42 if(a[i]<b[i]) 43 { 44 for (R j=0;j<=len;++j) 45 a[j]=b[j]; 46 return ; 47 } 48 } 49 } 50 51 void mul(int *a,int *b,int c) 52 { 53 len=b[0]; 54 for (R i=1;i<=len;++i) 55 a[i]=b[i]*c; 56 len+=3; 57 for (R i=1;i<=len;++i) 58 a[i+1]+=a[i]/10,a[i]%=10; 59 while (a[len]==0&&len) len--; 60 a[0]=len; 61 } 62 63 int main() 64 { 65 scanf("%d%d",&n,&m); 66 P[0][0]=P[0][1]=1; 67 for (R i=1;i<=80;++i) 68 { 69 P[i][0]=P[i-1][0]*2; 70 len=P[i][0]; 71 for (R j=1;j<=len;++j) 72 P[i][j]=P[i-1][j]*2; 73 for (R j=1;j<=len;++j) 74 P[i][j+1]+=P[i][j]/10,P[i][j]%=10; 75 while (P[i][len]==0&&len) len--; 76 P[i][0]=len; 77 } 78 for (R i=1;i<=n;++i) 79 for (R j=1;j<=m;++j) 80 scanf("%d",&a[i][j]); 81 for (R c=1;c<=n;++c) 82 { 83 memset(dp,0,sizeof(dp)); 84 memset(ansc,0,sizeof(ansc)); 85 for (R k=m;k>=1;k--) 86 for (R i=1;i+k-1<=m;i++) 87 { 88 j=i+k-1; 89 memset(t,0,sizeof(t)); 90 mul(t,P[m-k+1],a[c][i]); 91 add(t,dp[i][j]); 92 M(dp[i+1][j],t); 93 memset(t,0,sizeof(t)); 94 mul(t,P[m-k+1],a[c][j]); 95 add(t,dp[i][j]); 96 M(dp[i][j-1],t); 97 } 98 for (R i=1;i<=m;++i) 99 { 100 mul(ansc[i],P[m],a[c][i]); 101 add(ansc[i],dp[i][i]); 102 } 103 for (R i=1;i<=m;++i) 104 M(ansc[1],ansc[i]); 105 add(ans,ansc[1]); 106 } 107 len=ans[0]; 108 for (R i=len;i>=1;--i) 109 printf("%d",ans[i]); 110 if(len==0) printf("0"); 111 return 0; 112 }