洛谷 1541 乌龟棋

看题

这显然是一道线性的dp

如何设计状态呢?

看看题目,总共只有4张牌,而且每张牌的个数不超过40

于是状态就很好设计了

方程如下

  dp[i][j][k][l]=max(dp[i-1][j][k][l]+d[i*1+j*2+k*3+l*4],dp[i][j][k][l]);

  dp[i][j][k][l]=max(dp[i][j-1][k][l]+d[i*1+j*2+k*3+l*4],dp[i][j][k][l]);

  dp[i][j][k][l]=max(dp[i][j][k-1][l]+d[i*1+j*2+k*3+l*4],dp[i][j][k][l]);

  dp[i][j][k][l]=max(dp[i][j][k][l-1]+d[i*1+j*2+k*3+l*4],dp[i][j][k][l]);

第一维表示用了i张1,第二维表示用了j张2,以此类推

其实是可以压维的,因为有一种牌的数量可以由其他的牌数推出

但是我没有写,因为这题已经够了

代码很简单易懂

#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>
using namespace std;
const int N=50;
int n,m,dp[N][N][N][N],c[5],sum,x,d[1000];
int main()
{
    scanf("%d %d",&n,&m);
    for(int i=0;i<n;i++)
        scanf("%d",&d[i]);
    for(int i=1;i<=m;i++)
    {
        scanf("%d",&x);
        c[x]++;
        sum++;
    }
    dp[0][0][0][0]=d[0];
    for(int i=0;i<=c[1];i++)
    for(int j=0;j<=c[2];j++)
    for(int k=0;k<=c[3];k++)
    {
        for(int l=0;l<=c[4];l++)
        {
            if(i>=1)
                dp[i][j][k][l]=max(dp[i-1][j][k][l]+d[i*1+j*2+k*3+l*4],dp[i][j][k][l]);
            if(j>=1)
                dp[i][j][k][l]=max(dp[i][j-1][k][l]+d[i*1+j*2+k*3+l*4],dp[i][j][k][l]);
            if(k>=1)
                dp[i][j][k][l]=max(dp[i][j][k-1][l]+d[i*1+j*2+k*3+l*4],dp[i][j][k][l]);
            if(l>=1)
                dp[i][j][k][l]=max(dp[i][j][k][l-1]+d[i*1+j*2+k*3+l*4],dp[i][j][k][l]);    
        }
    }
    printf("%d
",dp[c[1]][c[2]][c[3]][c[4]]);
    return 0;
}
原文地址:https://www.cnblogs.com/wzrdl/p/9781831.html