P1541 [NOIP2010 提高组] 乌龟棋

[P1541 NOIP2010 提高组] 乌龟棋 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

问题描述:一行数字,一个乌龟在位置1处,有m张卡牌,卡牌上有1,2,3,4四个数字,使用完这个卡牌,乌龟可以向前爬行相应的格子,每一格都有不同的权重。问经过合理的顺序得到的最大的价值和,保证巧合到达终点N。

思路:数据范围很小。可以用四维dp,状态表示为用了i个卡牌1,用了j个卡牌2,用了k个卡牌3,用了z个卡牌4可以得到的最大价值和。

状态转移方程:
F ( i , j , k , z ) = { i ≠ 0 m a x ( F ( i , j , k , z ) , F ( i − 1 , j , k , z ) + v a l ) j ≠ 0 m a x ( F ( i , j , k , z ) , F ( i , j − 1 , k , z ) + v a ) k ≠ 0 m a x ( F ( i , j , k , z ) , F ( i , j , k − 1 , z ) + v a l ) z ≠ 0 m a x ( F ( i , j , k , z ) , F ( i , j , k , z − 1 ) + v a l ) v a l = a [ i ∗ 1 + j ∗ 2 + k ∗ 3 + z ∗ 4 + 1 ] 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(i,j,k,z)= i=0max(F(i,j,k,z),F(i1,j,k,z)+val)j=0max(F(i,j,k,z),F(i,j1,k,z)+va)k=0max(F(i,j,k,z),F(i,j,k1,z)+val)z=0max(F(i,j,k,z),F(i,j,k,z1)+val)val=a[i1+j2+k3+z4+1]
边界:
F ( 0 , 0 , 0 , 0 ) = a [ 0 ] F(0,0,0,0) = a[0] F(0,0,0,0)=a[0]
目标:
F ( m i i [ 1 ] , m i i [ 2 ] , m i i [ 3 ] , m i i [ 4 ] ) F(mii[1], mii[2], mii[3], mii[4]) 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]];
}

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