P1616 疯狂的采药 (完全背包优化)

Posted winter-bamboo

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P1616 疯狂的采药 (完全背包优化)相关的知识,希望对你有一定的参考价值。

(点击此处查看原题)

题意

简单来说,就是一个完全背包,不过这里卡住了常规的完全背包写法,时间复杂度为O( V*∑( V/c[i] ))如下所示:

for(int i = 1;i <= n ;i ++)
    
        scanf("%d%d",cost+i,val+i);
        for(int j = t; j >= cost[i] ; j --)
        
            for(int k = 1; k * cost[i] <= j ;k ++)
            
                dp[j] = max(dp[j],dp[j-k*cost[i]] + k * val[i]);
            
        
    

解题思路

既然普通的写法无法解决,那就采用如下的优化即可,时间复杂度为O(NV),题目满足N*T <= 1e7,因此可以跑过去:

for(int i = 1;i <= n ;i ++)
    
        scanf("%d%d",cost+i,val+i);
        for(int j = cost[i]; j <= t; j ++)
        
            dp[j] = max(dp[j],dp[j-cost[i]] + val[i]);
        
    

代码区

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
#include<string>
#include<fstream>
#include<vector>
#include<stack>
#include <map>
#include <iomanip>

#define bug cout << "**********" << endl
#define show(x, y) cout<<"["<<x<<","<<y<<"] "
#define LOCAL = 1;
using namespace std;
typedef long long ll;
const int inf = 1e9 + 7;
const ll mod = 1e9 + 7;
const int Max = 1e5 + 10;

int t, n;
int cost[Max],val[Max];
int dp[Max];            //记录价格为i的时候的最大价值

int main()

#ifdef LOCAL
    //    freopen("input.txt", "r", stdin);
    //    freopen("output.txt", "w", stdout);
#endif
    scanf("%d%d",&t,&n);
    memset(dp,0,sizeof(dp));
    for(int i = 1;i <= n ;i ++)
    
        scanf("%d%d",cost+i,val+i);
        for(int j = cost[i]; j <= t; j ++)
        
            dp[j] = max(dp[j],dp[j-cost[i]] + val[i]);
        
    
    printf("%d\n",dp[t]);
    return 0;

 

以上是关于P1616 疯狂的采药 (完全背包优化)的主要内容,如果未能解决你的问题,请参考以下文章

P1616 疯狂的采药 完全背包模型

背包模型题目集合

背包DP题单★

1616 疯狂的采药(完全背包问题)

P1616 疯狂的采药

洛谷——P1616 疯狂的采药