乌龟棋 【多维DP】 Codevs1068

来源:互联网 发布:网络效应多选题答案 编辑:程序博客网 时间:2024/05/23 19:14

因为 N < 40 所以这道题即使多维也不会MLE和TLE
设dp[i1][i2][i3][i4] 是使用了i1张1,i2张2,i3张3,i4张4后能得到的最大分数
需要注意dp[0][0][0][0]要设置为第一个格子的分数,不然会错
下面的代码中因为i1 i2 i3 i4一开始都是0 所以x+=t可以初始化dp[0][0][0][0]为第一个格子的分数

#include <cstdio>#include <algorithm>int n, m, m1, m2, m3, m4, a[360], b[130], dp[41][41][41][41];inline void read(int &x) {    x = 0;    char c = getchar();    while(c<'0'||c>'9') c = getchar();    while(c>='0'&&c<='9') x = x*10 + c -'0', c = getchar();    return;}int main() {    read(n);    read(m);    for(int i=1; i<=n; i++)         read(a[i]);    for(int i=1; i<=m; i++){        read(b[i]);        if(b[i] == 1)            m1++;        else if(b[i] == 2)            m2++;        else if(b[i] == 3)            m3++;        else if(b[i] == 4)            m4++;                   }       for(int i1=0; i1<=m1; i1++) {        for(int i2=0; i2<=m2; i2++) {            for(int i3=0; i3<=m3; i3++) {                for(int i4=0; i4<=m4; i4++) {                    int &x = dp[i1][i2][i3][i4];//使用引用可以少打点字                    int t = a[1+i1+2*i2+3*i3+4*i4];                    if(i1 > 0)                        x = std::max(x, dp[i1-1][i2][i3][i4]);                    if(i2 > 0)                        x = std::max(x, dp[i1][i2-1][i3][i4]);                      if(i3 > 0)                          x = std::max(x, dp[i1][i2][i3-1][i4]);                    if(i4 > 0)                        x = std::max(x, dp[i1][i2][i3][i4-1]);                      x += t;                 }            }        }    }       printf("%d",dp[m1][m2][m3][m4]);    return 0;}