乌龟棋

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了乌龟棋相关的知识,希望对你有一定的参考价值。

 原题链接:https://www.luogu.org/problem/show?pid=1541

超级暴力的四次方DP。

我们每次的决策是选择爬行卡片来决定乌龟棋的行动,那么好,我们用一个f数组记录使用i张1点数卡,j张2点数卡,k张3点数卡,l张4点数卡所能拿到的最多分数。

那么方程是f[i][j][k][l] =max(f[ i-1 ][ j ][ k ][ l ],f[ i ][ j-1 ][ k ][ l ],f[ i ][ j ][ k-1 ][ l ],f[ i ][ j ][ k ][ l-1 ]) + a[1 + i + j*2 + k*3 + l*4];//为了看起来方便

我们开一个数组记录每个点数的牌一共有多少张,然后从0到这个数枚举,进行转移就好。

我写的方法比较奇怪,我用了一个calc函数来计算转移,因为我发现直接转移数组越界了。。

不过不难理解就是了。

参考代码:

 1 #include <iostream>
 2 #define maxn 355
 3 #define N 55
 4 #define check cout << "ok" << endl;
 5 using namespace std;
 6 int f[N][N][N][N];
 7 int a[maxn];
 8 int n,m,point;
 9 int cnta[4];
10 
11 int calc(int x,int y,int z,int w){
12     int ans;
13     int temp[4];
14     ans = 0;
15     temp[1] = x;
16     temp[2] = y;
17     temp[3] = z;
18     temp[4] = w;
19     for (int i=1;i<=4;i++){
20         if ( temp[i] > 0 ){
21             temp[i]--;
22             if (ans < f[ temp[1] ][ temp[2] ][ temp[3] ][ temp[4] ])
23                 ans = f[ temp[1] ][ temp[2] ][ temp[3] ][ temp[4] ];
24             temp[i]++;
25         }
26     }
27     return ans;
28 }
29 
30 int main(){
31     cin >> n >> m;
32     for (int i=1;i<=n;i++)
33         cin >> a[i];
34     for (int i=1;i<=m;i++){
35         cin >> point;
36         cnta[point]++;
37     }
38 
39     f[0][0][0][0] = a[1];
40     for (int i = 0;i <= cnta[1];i++)
41         for (int j = 0;j <= cnta[2];j++)
42             for (int k = 0; k <= cnta[3];k++)
43                 for (int l = 0;l <= cnta[4];l++)
44                     if (a[1 + i + j*2 + k*3 + l*4] > 0)
45                         f[i][j][k][l] = calc(i,j,k,l) + a[1 + i + j*2 + k*3 + l*4];
46 
47     cout << f[ cnta[1] ][ cnta[2] ][ cnta[3] ][ cnta[4] ] << endl;
48     return 0;
49 }

 

以上是关于乌龟棋的主要内容,如果未能解决你的问题,请参考以下文章

题解乌龟棋

P1541 乌龟棋

P1541 乌龟棋

acm乌龟棋

[动态规划]乌龟棋

codevs 1068 乌龟棋