• 寻找线性增长的量的dp


    题意:给你一行a[i]的值,并且你手中有一组纸牌,纸牌上的数字说明你使用这张纸牌时能够向前走多少步。现在小明从a[ 1 ]出发,并且你每到达一个点都会把这个点上的数字加上。现在问当小明把手上的牌用完后,能得到的最大权值和。

    思路:一开始我想着以这一行数字的下标作为阶段,然后再用每个人手中的卡牌数量作为

    附加的维度来表示当前的状态。但是发现并不可做,因为小明所处的下标并不是线性增长的,

    它当前可能走1步也可能走5步,完全取决他出什么纸牌。所以以下标作为阶段不靠谱。所以

    只剩下卡牌数可以用来发挥了,因为小明每次只能出一张纸牌,所以,打出去的纸牌的数量是呈线性递增

    的,所以打出去的纸牌的数量完全可以当做阶段。现在小明所处的位置就是 1+a+b*2+c*3+d*4,这里一定要加

    1,因为小明的起始位置是1。然后为什么dp[ a ][ b ][ c ][ d ]=dp[ a-1 ][ b ][ c ][ d ]每次只能由一个维度减小1推出,因为每次

    只出一张牌呗。

    #include<bits/stdc++.h>
    using namespace std;
    
    int dp[125][125][125][125];
    int n,m;
    int w[360],card[150];
    int a_num,b_num,c_num,d_num;
    
    int main()
    {
        cin>>n>>m;
        for(int i=1;i<=n;i++)
        cin>>w[i];
    
         for(int i=1;i<=m;i++)
         {
         cin>>card[i];
         if(card[i]==1)
            a_num++;
         if(card[i]==2)
            b_num++;
         if(card[i]==3)
            c_num++;
         if(card[i]==4)
            d_num++;
         }
    
         dp[0][0][0][0]=w[1];
         for(int a=0;a<=a_num;a++)
          for(int b=0;b<=b_num;b++)
           for(int c=0;c<=c_num;c++)
            for(int d=0;d<=d_num;d++)
         {
             int r=1+a+b*2+c*3+d*4;
             if(a>=1) dp[a][b][c][d]=max(dp[a][b][c][d],dp[a-1][b][c][d]+w[r]);
             if(b>=1) dp[a][b][c][d]=max(dp[a][b][c][d],dp[a][b-1][c][d]+w[r]);
             if(c>=1) dp[a][b][c][d]=max(dp[a][b][c][d],dp[a][b][c-1][d]+w[r]);
             if(d>=1) dp[a][b][c][d]=max(dp[a][b][c][d],dp[a][b][c][d-1]+w[r]);
         }
    
         cout<<dp[a_num][b_num][c_num][d_num];
    
        return 0;
    }
  • 相关阅读:
    1.Go环境安装
    IDEA启动Tomcat控制台中文显示乱码
    专注的含义
    翻出一封古老的信
    若有所思
    B+Tree与B-Tree 的区别
    Redis集群 什么是slots
    夜深人静,听雨
    随心所想
    本性可以改吗
  • 原文地址:https://www.cnblogs.com/rainyskywx/p/11230081.html
Copyright © 2020-2023  润新知