01简单背包问题&十四届华中科技程序设计竞赛总决赛F题(背包简单变形)&超大背包

一 最简单的背包问题(重量比较小)

重量和价值分别为w[i],v[i]的n个物品,从这些物品中挑选总重量不超过W的物品,求所有挑选方案中价值总和的最大值

用dp[i][j]表示前i个物品放进容量为j的最大价值

有状态方程 dp[i][j]=max(dp[i-1][j],dp[i-1][j-w[i]]+v[i])

降低空间复杂度:我们发现dp[i][j]是由dp[i-1][j]推出来的,循环中我们以j=j..0的顺序推f[j],那么推f[j]时肯定是由前面的状态推出来的

 

for i=1..N

    for j=j..0

        f[j]=max{f[j],f[j-c[i]]+v[i]};

 

当重量特别大时,n和v[i]比较小时,我们可以用dp[n*max(v[i])] 表示多少价值的最小容量,如题

链接:https://www.nowcoder.com/acm/contest/119/F
来源:牛客网

 

It’s universally acknowledged that there’re innumerable trees in the campus of HUST.
Now HUST got a big land whose capacity is C to plant trees. We have n trees which could be plant in it. Each of the trees makes HUST beautiful which determined by the value of the tree. Also each of the trees have an area cost, it means we need to cost ci area of land to plant.
We know the cost and the value of all the trees. Now HUSTers want to maximize the value of trees which are planted in the land. Can you help them?

输入描述:

There are multiple cases.
The first line is an integer T(T≤10), which is the number of test cases.
For each test case, the first line is two number n(1≤n≤100) and C(1≤C≤108), the number of seeds and the capacity of the land. 
Then next n lines, each line contains two integer ci(1≤ci≤106) and vi(1≤vi≤100), the space cost and the value of the i-th tree.

输出描述:

For each case, output one integer which means the max value of the trees that can be plant in the land.
示例1

输入

复制
1
3 10
5 10
5 10
4 12

输出

复制
22

状态转移方程为     dp[i][j]=min(dp[i][j-v[i]]+w[i],dp[i][j])  那么这个数组只要开到n*max(v[i]),因为可能所有的物品都加入

和简单背包问题一样可以优化空间复杂度

#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
const int INF =0x3f3f3f;
int cost[105],value[105];
int dp[10005];
int main()
{
    int t,n,c;
    scanf("%d",&t);
    while(t--){
        memset(dp,INF,sizeof(dp));
        scanf("%d%d",&n,&c);
        for(int i=1;i<=n;i++) scanf("%d%d",&cost[i],&value[i]);
        dp[0]=0;
        //dp[value[1]]=cost[1];
        for(int i=1;i<=n;i++)
         for(int j=10000;j>=value[i];j--)
         {
            dp[j]=min((dp[j-value[i]]+cost[i]),dp[j]);
         }
         int ans=0;
         for(int i=1;i<=10000;i++)
            if(dp[i]<=c)
         {
             ans=i;
         }
         printf("%d\n",ans);
    }




    return 0;
}

 

三:超大背包问题,n比较小,价值和重量大

 

这篇博文讲的很好

https://blog.csdn.net/a2459956664/article/details/51190756

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值