题解 P1541 【乌龟棋】

hicc0305

2017-07-18 19:20:13

Solution

其实这道题想到了就很简单,但很难想到用四维的dp,这非常少见。 看到每张牌不超过40张,这数据范围就是给你开四维dp的 自然想到用dp[ i ][ j ][ k ][ l ]表示用了i张1,j张2,k张3 , l 张4的最大值 用i张1,j张2,k张3 , l 张4自然跳到了 第(1+i+2\*j+3\*k+4\*l)格,枚举四种情况,再加上第(1+i+2\*j+3\*k+4\*l)格的值就行了 转移方程见代码,打起来太烦了……………… ```cpp #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; int n,m; int a[351]; int c[5]={0}; int dp[41][41][41][41]={0}; 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); c[x]++; //统计每张牌的数量 } 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++) //枚举 dp[i][j][k][l]=max(max(max(dp[max(0,i-1)][j][k][l],dp[i][max(0,j-1)][k][l]),dp[i][j][max(0,k-1)][l]),dp[i][j][k][max(0,l-1)])+a[1+i+2*j+3*k+4*l]; //四种情况的转移方程。怀疑是史上最长………… printf("%d",dp[c[1]][c[2]][c[3]][c[4]]); //用完牌就到达了终点,输出即可 return 0; } ```