P1541 [NOIP2010 提高组] 乌龟棋

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]];
}

你可能感兴趣的:(算法题,算法)