洛谷$1541$ 乌龟棋 线性$DP$
Sol
f[i]表示走到第i个格子时获得的最大分数
发现转移与各个爬行卡片的数量有关,一共只有4种卡片
所以就把这四种卡片的已使用张数也放进状态,f[i][a][b][c][d]...
发现知道a,b,c,d后已得知i,所以减去i的一维,只剩下f[a][b][c][d]
综上,最终状态是f[a][b][c][d]表示1牌用了a张,2牌用了b张.....获得的最大分数
转移就枚举上一张用的是哪张牌转移即可
Code
1 #include<iostream> 2 #include<cstdio> 3 #define go(i,u,v) for(register int i=u;i<=v;i++) 4 using namespace std; 5 int read() 6 { 7 int x=0,y=1;char c=getchar(); 8 while(c<'0'||c>'9') {if(c=='-') y=-1;c=getchar();} 9 while(c>='0'&&c<='9') {x=(x<<3)+(x<<1)+c-'0';c=getchar();} 10 return x*y; 11 } 12 int n,m,cd[5],sc[360],f[50][50][50][50]; 13 int main() 14 { 15 n=read();m=read(); 16 go(i,1,n) sc[i]=read(); 17 go(i,1,m) {int x=read();cd[x]++;} 18 f[0][0][0][0]=sc[1]; 19 go(a,0,cd[1]) go(b,0,cd[2]) 20 go(c,0,cd[3]) go(d,0,cd[4]){ 21 int x=a*1+b*2+c*3+d*4+1; 22 if(a>0) f[a][b][c][d]=max(f[a][b][c][d],f[a-1][b][c][d]+sc[x]); 23 if(b>0) f[a][b][c][d]=max(f[a][b][c][d],f[a][b-1][c][d]+sc[x]); 24 if(c>0) f[a][b][c][d]=max(f[a][b][c][d],f[a][b][c-1][d]+sc[x]); 25 if(d>0) f[a][b][c][d]=max(f[a][b][c][d],f[a][b][c][d-1]+sc[x]); 26 } 27 printf("%d",f[cd[1]][cd[2]][cd[3]][cd[4]]); 28 return 0; 29 }
光伴随的阴影