zoukankan      html  css  js  c++  java
  • Comet OJ

    题意:你要计算如下模型能得到的最大钱数:

    有 n 天,初始时你的钱数为 0,有 m 种可能操作,第 i 种会使你当前失去 ai 的钱数并在 n 天结束后返还 bi 的钱数。每一天可以执行任意多种操作,每种任意次(但每次操作后你的钱数不能为负)。每天结束时你会获得一个与当前持有钱数 x 相关的收入f(x) ,而 f(x) 单调不增。

    分析:首先显然是动态规划,并且状态可分解为 前 i 天、当前持有钱数、最后能获得的投资回报。 选择较小的两个作为数组下标,最大的作为值。

    那么 状态转移方程: 第 i 天获得津贴节点的过程转移为

    dp[ i ][ j+w[ j ] ] = max( dp[ i ][ j+w[ j ] ], dp[ i-1 ][ j ] )  就比如第二天的某个状态是由前一天的状态转移来的。

    而对于存储 节点的过程,只需对每一种存储方式做一个完全背包即可。

    注意:这个完全背包的状态是一个新的形式,众所周知,基础的背包问题的状态 j 都是指总容量,而本题的状态 j 是指手头上的钱,也就是剩余的容量。模拟现实理解一下就知道这个状态转移方程怎么写了。注意枚举方向。

    注意:还没有转移到的状态为无效状态 , 需要置为很小的负数.

    #include <bits/stdc++.h>
    using namespace std;
    
    const int inf = 0x3f3f3f3f;
    int a[105],b[105];
    int w[1005];
    int dp[105][1005+1005];  //表示的状态是第i天 手头上!剩余!的钱 (值)最多可以投资得到多少钱
    
    int main(){
        int n,m,k;
        scanf("%d %d %d",&n,&m,&k);
        for(int i=0; i<=k; i++){
            scanf("%d",w+i);
        }
        for(int i=1; i<=m; i++){
            scanf("%d %d",a+i,b+i);
        }
    
        for(int i=1; i<=n; i++){
            for(int j=0; j<=2005; j++){
                dp[i][j] = -inf;
            }
        }
        dp[1][0] = 0;
    
        for(int i=2; i<=n; i++){
            for(int j=0; j<=1000; j++){
                dp[i][ j+w[j] ] = max(dp[i][ j+w[j] ], dp[i-1][j]);
            }   
            for(int k=1; k<=m; k++){
                for(int j=1000; j>=0; j--){
                    dp[i][j] = max(dp[i][j], dp[i][ j+a[k] ]+b[k] );   //这里普通背包的j是指总容量,而这是指剩余的容量,也就是手头上的钱,所以模拟现实理解一下就知道状态转移方程怎么写了
                } 
            }
        }
        int ans=-1;
        for(int i=0; i<=1000; i++){
            ans = max(ans, dp[n][i]+i+w[i]);
        }
        printf("%d
    ", ans);
    }
  • 相关阅读:
    Servlet学习笔记3
    Servlet学习笔记2
    Servlet 学习笔记1
    Response对象学习笔记
    【JavaSE】异常
    【JavaSE】格式化输出
    【JavaSE】泛型
    【JavaSE】集合
    【SpringBoot】(1)-- 基于eclipse配置springboot开发环境
    【Linux】(1)安装
  • 原文地址:https://www.cnblogs.com/-Zzz-/p/11588135.html
Copyright © 2011-2022 走看看