乌龟棋 【多维DP】 Codevs1068

本文介绍了一种解决特定背包问题的方法,通过四维动态规划算法来求解最大分数。利用dp[i1][i2][i3][i4]表示使用不同数量的卡片后能达到的最大分数,并给出了完整的C++实现代码。

因为 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;
}
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值