【问题描述】
小明过生日的时候,爸爸送给他一副乌龟棋当作礼物。
对于30%的数据有1≤N≤30,1≤M≤12。
对于50%的数据有1≤N≤120,1≤M≤50,且4种爬行卡片,每种卡片的张数不会超
过20。
对于100%的数据有1≤N≤350,1≤M≤120,且4种爬行卡片,每种卡片的张数不会
超过40;0≤ai≤100,1≤i≤N;1≤bi≤4,1≤i≤M。
解题思路:这种分步决策的问题先考虑动态规划。。由于有4种不同的卡片,所以我们肯定要在状态上把这个反映出来,要不然显然转移不了状态。。还有一点就是我们知道了四种卡片用了的数量我们自然就可以知道走了多少步,这样一来问题就很简单了。f[x1][x2][x3][x4]表示四种卡片分别用了x1,x2,x3,x4张时的最大得分,容易得到f[x1][x2][x3][x4]=max(f[x1-1][x2][x3][x4],f[x1][x2-1][x3][x4],f[x1][x2][x3-1][x4],f[x1][x2][x3][x4-1])+a[x1+x2*2+x3*3+x4*4]。
代码:
#include
#include
#include
using namespace std;
int f[42][42][42][42],i,n,m,num[5],a[400],k,l1,l2,l3,l4;
int main()
{scanf("%d%d",&n,&m);
for (i=1;i<=n;i++)
scanf("%d",&a[i]);
memset(num,0,sizeof(num));
for (i=1;i<=m;i++)
{scanf("%d",&k);
num[k]++;
}
memset(f,0,sizeof(0));
int t;
f[0][0][0][0]=a[1];
for (l1=0;l1<=num[1];l1++)
for (l2=0;l2<=num[2];l2++)
for(l3=0;l3<=num[3];l3++)
for(l4=0;l4<=num[4];l4++)
{t=l1+l2*2+l3*3+l4*4+1;
if(l1)f[l1][l2][l3][l4]=max(f[l1][l2][l3][l4],f[l1-1][l2][l3][l4]+a[t]);
if(l2)f[l1][l2][l3][l4]=max(f[l1][l2][l3][l4],f[l1][l2-1][l3][l4]+a[t]);
if(l3)f[l1][l2][l3][l4]=max(f[l1][l2][l3][l4],f[l1][l2][l3-1][l4]+a[t]);
if(l4)f[l1][l2][l3][l4]=max(f[l1][l2][l3][l4],f[l1][l2][l3][l4-1]+a[t]);
}
printf("%d",f[num[1]][num[2]][num[3]][num[4]]);
}