不充钱,你怎么AC?
题目:http://codevs.cn/problem/1068/
这是一道神DP题,一开始状态设计错了,用位置和剩余卡片做下标,过了样例数据WA了
好了,讲正解,设 f[i][j][k][l] 为1卡牌用了 i 次,2卡牌用了 j 次,3卡牌用了 k 次,4卡牌用了 l 次
那么转移:
这里 c 数组存的是对应的卡牌一共有多少张,末状态是 f[c[1]][c[2]][c[3]][c[4]]
时间复杂度:
1 #include<algorithm> 2 #include<iostream> 3 #include<cstdlib> 4 #include<cstring> 5 #include<cstdio> 6 #include<cmath> 7 #define C 41 8 #define N 351 9 using namespace std; 10 11 int f[C][C][C][C],c[5],n,m,a[N]; 12 int main() 13 { 14 int i,j,k,l; 15 scanf("%d%d",&n,&m); 16 for (i=1;i<=n;i++) scanf("%d",&a[i]); 17 for (i=1;i<=m;i++) 18 { 19 scanf("%d",&k); 20 c[k]++; 21 } 22 f[0][0][0][0]=a[1]; 23 for (i=0;i<=c[1];i++) 24 { 25 for (j=0;j<=c[2];j++) 26 { 27 for (k=0;k<=c[3];k++) 28 { 29 for (l=0;l<=c[4];l++) 30 { 31 if (i>0) f[i][j][k][l]=max(f[i][j][k][l],f[i-1][j][k][l]+a[1+i+j*2+k*3+l*4]); 32 if (j>0) f[i][j][k][l]=max(f[i][j][k][l],f[i][j-1][k][l]+a[1+i+j*2+k*3+l*4]); 33 if (k>0) f[i][j][k][l]=max(f[i][j][k][l],f[i][j][k-1][l]+a[1+i+j*2+k*3+l*4]); 34 if (l>0) f[i][j][k][l]=max(f[i][j][k][l],f[i][j][k][l-1]+a[1+i+j*2+k*3+l*4]); 35 } 36 } 37 } 38 } 39 printf("%d ",f[c[1]][c[2]][c[3]][c[4]]); 40 return 0; 41 }