题目传送门

解题思路:

一开始脑抽,以为是一道背包,结果写完后发现并不是一道背包.....

f[i][j][x][y]表示1,2,3,4种牌各用了i,j,x,y张可以获得的最大值.

AC代码:

 1 #include<iostream>
 2 #include<cstdio>
 3 #define f(i,j,x,y) f[i][j][x][y]
 4
 5 using namespace std;
 6
 7 int n,m,a[351],sum[5],f[41][41][41][41];
 8
 9 int main() {
10     scanf("%d%d",&n,&m);
11     for(int i = 1;i <= n; i++)
12         scanf("%d",&a[i]);
13     f(0,0,0,0) = a[1];
14     for(int i = 1;i <= m; i++) {
15         int u;
16         scanf("%d",&u);
17         sum[u]++;
18     }
19     for(int i = 0;i <= sum[1]; i++)
20         for(int j = 0;j <= sum[2]; j++)
21             for(int x = 0;x <= sum[3]; x++)
22                 for(int y = 0;y <= sum[4]; y++) {
23                     int now = 1 * i + 2 * j + 3 * x + 4 * y + 1;
24                     if(i != 0) f(i,j,x,y) = max(f(i,j,x,y),f(i-1,j,x,y) + a[now]);
25                     if(j != 0) f(i,j,x,y) = max(f(i,j,x,y),f(i,j-1,x,y) + a[now]);
26                     if(x != 0) f(i,j,x,y) = max(f(i,j,x,y),f(i,j,x-1,y) + a[now]);
27                     if(y != 0) f(i,j,x,y) = max(f(i,j,x,y),f(i,j,x,y-1) + a[now]);
28                 }
29     printf("%d",f(sum[1],sum[2],sum[3],sum[4]));
30     return 0;
31 }

//NOIP提高2010 T2

 

01-08 10:52