题目大意
- 一个n格的跑道,每个格子上有得分;
- 要求乌龟从第一格走到第n格,有4种共m张牌可以用;
- 1号牌可以移动1格,2号派可以移动2格。。。计算落脚点的得分;
- 数据保证刚好卡牌用完,落在终点,问如何调整牌的顺序,得到最大得分。
题目分析
- 第一个感觉就是背包,而且隐藏了很多信息:
1 而且数据保证,用完m张牌,刚好到达终点;
2 从1 出发,到达n,所以只走了n-1步;
思路:
看他写就好
参考代码
//luogu1541:乌龟棋:带技巧的背包
//f[x][y][i][j] 表示:拿x张1号,y张2号,i张3号,j张4号卡,得到的最大值
#include<bits/stdc++.h>
using namespace std;
#define mn 42
int f[mn][mn][mn][mn];
int n,m,a[400];
int s[mn];
int main()
{
scanf("%d %d",&n,&m);
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
for(int i=1;i<=m;i++)
{
int x; scanf("%d",&x);
s[x]++;
}
f[0][0][0][0]=a[1];//每张牌都不拿,则站在第一格的得分
for(int i=0;i<=s[1];i++)
{
for(int j=0;j<=s[2];j++)
{
for(int x=0;x<=s[3];x++)
{
for(int y=0;y<=s[4];y++)
{
int t=i+j*2+x*3+y*4+1;//当前走t步,到达[t+1]的位置(从1出发的)
if(i!=0) f[i][j][x][y]=max(f[i][j][x][y],f[i-1][j][x][y]+a[t]);
if(j!=0) f[i][j][x][y]=max(f[i][j][x][y],f[i][j-1][x][y]+a[t]);
if(x!=0) f[i][j][x][y]=max(f[i][j][x][y],f[i][j][x-1][y]+a[t]);
if(y!=0) f[i][j][x][y]=max(f[i][j][x][y],f[i][j][x][y-1]+a[t]);
}
}
}
}
printf("%d",f[s[1]][s[2]][s[3]][s[4]]);
return 0;
}