[ CodeVS冲杯之路 ] P1068

  不充钱,你怎么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 }
原文地址:https://www.cnblogs.com/hadilo/p/5864763.html