zoukankan      html  css  js  c++  java
  • P1541乌龟棋

    传送

    这题咋做?

    当然是爆搜了。

    但是蒟蒻不会爆搜(TLE,WA两开花qwq),更不会记忆化搜索,所以我们换个思路。

    注意这句话:

    这肯定是有用的(洛咕还不会闲圈到给一句毛用都没有的话),那它有什么用呢?

    我们再想一想,出牌的顺序与爬行牌的输入顺序没有半毛钱的关系,所以我们完全可以把牌分为4类,统计每种牌的个数。

    这样一来,似乎看到了dp的影子。没错我们就是要用四维dp。而且上面的数据保证不会爆空间。

    设计状态:dp[i][j][k][o]表示1的牌用i张,2的牌用j张,3的牌用k张,4的牌用o张时的最大得分。

    转移方程:dp[i][j][k][o]=max(dp[i][j][k][o],dp[i-1][j][k][o],dp[i][j-1][k][o],dp[i][j][k-1][o],dp[i][j][k][o-1])其中i>0,j>0,k>0,o>0(因为如果等于0,-1后会造成-1下标)

    初始状态:dp[0][0][0][0]=fen[1](第一个格子的分数),因为什么牌都不用的时候的初始分数是第一个格子的分数。

    最后答案就是所有牌都出完了的分数。

    直接上代码

    #include<bits/stdc++.h>
    #define ll long long
    const ll inf=2147483647; 
    using namespace std;
    int read()
    {
        char ch=getchar();
        int x=0;bool f=0;
        while(ch<'0'||ch>'9')
        {
            if(ch=='-')f=1;
            ch=getchar();
        }
        while(ch>='0'&&ch<='9')
        {
            x=(x<<3)+(x<<1)+(ch^48);
            ch=getchar();
        }
        return f?-x:x;
    }
    int n,m,fen[359],pai[5];//pai[i]是内容为i的牌的数量,fen[i]是第i个格子的分值     
    int dp[49][49][49][49];
    int main()
    {
        n=read();m=read();
        for(int i=1;i<=n;i++)
         fen[i]=read();
        for(int i=1;i<=m;i++)
         pai[read()]++;
         dp[0][0][0][0]=fen[1];
        for(int i=0;i<=pai[1];i++)//注意是要从0开始,因为我们可以不用某种牌
        {
            for(int j=0;j<=pai[2];j++)
            {
                for(int k=0;k<=pai[3];k++)
                {
                    for(int o=0;o<=pai[4];o++)
                    { 
                       int r=1+i+2*j+k*3+o*4;//用完牌后,当前的位置
                      if(i!=0)dp[i][j][k][o]=max(dp[i-1][j][k][o]+fen[r],dp[i][j][k][o]);//zhuyiyaopan0,fouzehuizha
                      if(j!=0)dp[i][j][k][o]=max(dp[i][j-1][k][o]+fen[r],dp[i][j][k][o]);
                      if(k!=0)dp[i][j][k][o]=max(dp[i][j][k-1][o]+fen[r],dp[i][j][k][o]);
                      if(o!=0)dp[i][j][k][o]=max(dp[i][j][k][o-1]+fen[r],dp[i][j][k][o]);
                    }
                }
            }
        }
        printf("%d",dp[pai[1]][pai[2]][pai[3]][pai[4]]);  
    }
  • 相关阅读:
    hdu 1250 简单大整数加法
    hdu 3594 强连通好题仙人掌图,对自己的tarjan模板改下用这个
    hdu 1568关于斐波那契数列的公式及其思维技巧
    hdu 1245 Saving James Bond 策画几何+最短路 最短路求步数最少的路径
    关于c对文件的操作
    hdu 1829 带权并查集的运用类似于食物链但是更简单些
    hdu 1716 深搜dfs
    hdu 1713求分数的最小公倍数
    1268 和为K的组合 Meet in mid二分思路
    1163 最高的奖励 贪心 + 并查集
  • 原文地址:https://www.cnblogs.com/lcez56jsy/p/11151155.html
Copyright © 2011-2022 走看看