首页 > 其他 > 详细

洛谷 1541 乌龟棋

时间:2019-10-22 19:40:50      阅读:87      评论:0      收藏:0      [点我收藏+]

既然我放在动态规划这个分类,不是动态规划是什么???

既然没有规定乌龟卡的使用顺序,那么用桶排,sum[i]记录i类卡的张数。

状态设计:当数据范围不大,并且情况不多的题,可以试试每一维记录一个元素的状态。dp[a][b][c][d]代表用了a张1类牌,b张2类牌,c张3类牌和d张4类牌时可以获得的最大价值。

边界条件:当dp[0][0][0][0]时,没有用牌,那么站在原地1处,获得的价值是v[1]。

转移方程:4重循环分别枚举a,b,c,d从0到sum[],四种类型的乌龟牌分别用了几张,step计算了这次如果转移可以获得多少价值,下面用分支结构一一讨论:

(1)如果a不为0  dp[a][b][c][d]=max(dp[a][b][c][d],dp[a-1][b][c][d]+step);

(2)如果b不为0  dp[a][b][c][d]=max(dp[a][b][c][d],dp[a][b-1][c][d]+step);

(3)如果c不为0  dp[a][b][c][d]=max(dp[a][b][c][d],dp[a][b][c-1][d]+step);

(4)如果d不为0  dp[a][b][c][d]=max(dp[a][b][c][d],dp[a][b][c][d-1]+step);

这样做的原因是数组的下标为非负数,答案自然是dp[sum[1]][sum[2]][sum[3]][sum[4]]。

 

#include<bits/stdc++.h>
using namespace std;
const int N=355,M=10,T=125;
int n,m,v[N],sum[M],dp[T][T][T][T];
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)   scanf("%d",&v[i]);
    memset(sum,0,sizeof(sum));
    for(int i=1;i<=m;i++)
    {
        int x;
        scanf("%d",&x);
        sum[x]++;
    }
    dp[0][0][0][0]=v[1];
    for(int a=0;a<=sum[1];a++)
        for(int b=0;b<=sum[2];b++)
            for(int c=0;c<=sum[3];c++)
                for(int d=0;d<=sum[4];d++)
                {
                    int step=a*1+b*2+c*3+d*4+1;
                    step=v[step];
                    if(a!=0)    dp[a][b][c][d]=max(dp[a][b][c][d],dp[a-1][b][c][d]+step);
                    if(b!=0)    dp[a][b][c][d]=max(dp[a][b][c][d],dp[a][b-1][c][d]+step);
                    if(c!=0)    dp[a][b][c][d]=max(dp[a][b][c][d],dp[a][b][c-1][d]+step);
                    if(d!=0)    dp[a][b][c][d]=max(dp[a][b][c][d],dp[a][b][c][d-1]+step);
                }
    printf("%d\n",dp[sum[1]][sum[2]][sum[3]][sum[4]]);
    return 0;
}

 

洛谷 1541 乌龟棋

原文:https://www.cnblogs.com/Siv0106/p/11721926.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!