摘要

题目链接 难度等级 完成状态 完成分数 最后编辑时间 失误原因(初次提交分数)
乌龟棋 ★★☆☆☆ 答案正确 100 2014/11/04 20:37:43 数组不够大(60)

题意

在1~N格子中,要从第一个格子走到第N个,每走到一个格子可以获得格子不同的价值。有至多四种前进步数(四种乌龟卡),每种步数只能使用固定次数,求到终点能获得的最大价值总和。

题解

嗯。四重for的DP,转移方程是:

显示/移除行号
  1. f(每种卡片分别用了i,j,k,l张)=
  2. 当前所在格子的价值
  3. +
  4. max{
  5. f(每种卡片分别用了i-1,j,k,l张),
  6. f(每种卡片分别用了i,j-1,k,l张),
  7. f(每种卡片分别用了i,j,k-1,l张),
  8. f(每种卡片分别用了i,j,k,l-1张)
  9. };

DP方程蛮好理解的,但是太久没做真的不好想[1]

代码

1068.cpp代码已折叠
展开折叠内容
显示/移除行号
  1. #include<map>
  2. #include<cstdio>
  3. #include<iterator>
  4. #include<algorithm>
  5. std::map<int,int> cardM;
  6. int n,m,f[50][50][50][50]={},score[500]={},cardN[4]={},cardP[4]={};
  7. int main()
  8. {
  9. scanf("%d%d",&n,&m);
  10. for(int i=1;i<=n;++i)
  11. scanf("%d",&score[i]);
  12. for(int i=1,pace;i<=m;++i)
  13. {
  14. scanf("%d",&pace);
  15. cardM[pace]++;
  16. }
  17. int p=0;
  18. for(std::map<int,int>::iterator i=cardM.begin();i!=cardM.end();++i,++p)
  19. {
  20. cardP[p]=i->first;
  21. cardN[p]=i->second;
  22. }
  23. for(int i=0;i<=cardN[0];++i)
  24. for(int j=0;j<=cardN[1];++j)
  25. for(int k=0;k<=cardN[2];++k)
  26. for(int l=0;l<=cardN[3];++l)
  27. {
  28. int s=i*cardP[0]+j*cardP[1]+k*cardP[2]+l*cardP[3]+1;
  29. if(i)f[i][j][k][l]=std::max(f[i][j][k][l],f[i-1][j][k][l]+score[s]);
  30. if(j)f[i][j][k][l]=std::max(f[i][j][k][l],f[i][j-1][k][l]+score[s]);
  31. if(k)f[i][j][k][l]=std::max(f[i][j][k][l],f[i][j][k-1][l]+score[s]);
  32. if(l)f[i][j][k][l]=std::max(f[i][j][k][l],f[i][j][k][l-1]+score[s]);
  33. }
  34. printf("%d",f[cardN[0]][cardN[1]][cardN[2]][cardN[3]]+score[1]);
  35. return 0;
  36. }

参考资料

  1. 跳转 http://tieba.baidu.com/p/1144676453

著作权声明[编辑]

关于[编辑]