https://www.luogu.com.cn/problem/P1541
问题描述:一行数字,一个乌龟在位置1处,有m张卡牌,卡牌上有1,2,3,4四个数字,使用完这个卡牌,乌龟可以向前爬行相应的格子,每一格都有不同的权重。问经过合理的顺序得到的最大的价值和,保证巧合到达终点N。
思路:数据范围很小。可以用四维dp,状态表示为用了i个卡牌1,用了j个卡牌2,用了k个卡牌3,用了z个卡牌4可以得到的最大价值和。
状态转移方程:
$$
F(i,j,k,z) = \begin{cases}
i \not= 0 \quad max(F(i,j,k,z), F(i-1,j,k,z) + val) \
j \not= 0 \quad max(F(i,j,k,z), F(i,j-1,k,z) + va) \
k \not= 0 \quad max(F(i,j,k,z), F(i,j,k-1,z) + val) \
z \not= 0 \quad max(F(i,j,k,z), F(i,j,k,z-1) + val) \
val = a[ i * 1 + j * 2 + k * 3 + z*4 + 1]
\end{cases}
边界: 边界: 边界:
F(0,0,0,0) = a[0]
目标: 目标: 目标:
F(mii[1], mii[2], mii[3], mii[4])
$$
AC代码:
int f[N][N][N][N];
int a[N];
void inpfile();
void solve() {
map<int,int> mii;
int n,m; cin>>n>>m;
rep(i,1,n) cin>>a[i];
rep(i,1,m) {
int t; cin>>t; mii[t]++;
}
f[0][0][0][0] = a[1];
rep(i,0,mii[1]) {
rep(j,0,mii[2]) {
rep(k,0,mii[3]) {
rep(z,0,mii[4]) {
int idx = i + 2 * j + 3 * k + 4 * z + 1;
int val = a[idx];
// cout<
if(i) f[i][j][k][z] = max(f[i][j][k][z], f[i-1][j][k][z] + val);
if(j) f[i][j][k][z] = max(f[i][j][k][z], f[i][j-1][k][z] + val);
if(k) f[i][j][k][z] = max(f[i][j][k][z], f[i][j][k-1][z] + val);
if(z) f[i][j][k][z] = max(f[i][j][k][z], f[i][j][k][z-1] + val);
}
}
}
}
cout<<f[ mii[1]][ mii[2]][ mii[3]][ mii[4]];
}