zoukankan      html  css  js  c++  java
  • P1855 榨取kkksc03

    题目:

    传送门

    思路:

    //该动归的状态设置为从前k个愿望中挑选剩余时间i金钱j所实现的愿望个数
    //很明显 这里的限制条件有了金钱和时间 另外加上愿望数量 从而dp数组扩展到了三维
    //dp[i][j][k]代表的是从前k个愿望中剩余时间i和金钱j 所能实现的愿望个数
     
    核心套路(动归通用):
    ①先判断党当前剩余的钱和时间是否满足当下的愿望k(即第k个愿望)  如果不满足 则当前状态等于前k-1愿望个数
    ②否则进行判断当前 “选择第k个愿望”和“不选择第k个愿望”哪个更大,取最大值
    对应代码如下:
    if(i>=ti[k]&&j>=mo[k]){     //代表时间金钱足够
         dp[i][j][k]=max(dp[i][j][k-1],dp[i-ti[k]][j-mo[k]][k-1]+1);         //对于k挑选和不挑中二选1
    }else{          //代表当前愿望k无法满足  直接跳到下一个愿望
         dp[i][j][k]=dp[i][j][k-1];          //没花钱和时间 并且愿望数也没增加
    }
    完整代码:
    #include<iostream>
    #include<algorithm>
    using namespace std;
    
    int dp[205][205][105]={0};          //确保了边缘赋值的情况
    int mo[105];
    int ti[105];
    int n,m,t;
    
    int main(){
        cin>>n>>m>>t;
    
        for(int i=1;i<=n;i++){
            cin>>mo[i]>>ti[i];
        }
    
    
        for(int i=0;i<=t;i++){          //dp三个状态分量 所以三重循环
            for(int j=0;j<=m;j++){
                for(int k=1;k<=n;k++){
                    if(i>=ti[k]&&j>=mo[k]){     //代表时间金钱足够
                        dp[i][j][k]=max(dp[i][j][k-1],dp[i-ti[k]][j-mo[k]][k-1]+1);         //对于k挑选和不挑中二选1
                    }else{          //代表当前愿望k无法满足  直接跳到下一个愿望
                        dp[i][j][k]=dp[i][j][k-1];          //没花钱和时间 并且愿望数也没增加
                    }
                }
            }
        }
    
        cout<<dp[t][m][n];      //最终状态
        return 0;
    }
     
  • 相关阅读:
    LDAP+Jenkins
    LDAP+SASL+SVN
    Ubuntu下的LDAP服务搭建
    LDAP+Confluence
    LDAP+Nextcloud
    vim -d
    linux默认编辑器
    vim相关调优
    MySQL中的保留字
    RHEL7配置ip地址
  • 原文地址:https://www.cnblogs.com/xwh-blogs/p/13805033.html
Copyright © 2011-2022 走看看