背包问题 2017-7-24

01 背包

在N件物品取出若干件放在容量为W的背包里,每件物品的体积为W1,W2……Wn(Wi为整数),与之相对应的价值为P1,P2……Pn(Pi为整数)。求背包能够容纳的最大价值。

#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;
const int maxn = 100 + 5;

int n ,w;
int v[maxn],s[maxn];
int dp[2][10010];

int main()
{
    cin>> n >> w;
    for(int i=1;i <= n;i++){
        cin >> v[i] >> s[i];
    }
    int now = 1,pre = 0;
    for(int i=1;i <= n;i++)
    {
        for(int j=0;j<=w;j++)
        {
            if(j < v[i])
                dp[now][j] = dp[pre][j];
            else
                dp[now][j] = max(dp[pre][j] , dp[pre][j-v[i]]+s[i]); // 不选 就是dp[i-1][j]
                //选就是dp[i-1][j-v[i]]+s[i]
        }
        swap (now,pre);
    }
    cout<< dp[pre][w]<<endl;
    return 0;
}

01 背包

下面是优化过内存的

#include <iostream>
#include <cstdio>
#include <cmath>
#include <string.h>
using namespace std;
const int maxn = 100 + 5;

int n ,w;
int v[maxn],s[maxn];
int dp[10010];

int main()
{
    cin>> n >> w;
    for(int i=1;i <= n;i++){
        cin >> v[i] >> s[i];
    }
    memset(dp,0,sizeof(dp));
    for(int i=1;i <= n;i++)
    {
        for(int j=w;j >= v[i];j--)//从上面一个状态转移 但是倒着写 上面一个状态就不会转移了
            dp[j] = max(dp[j] , dp[j-v[i]]+s[i]);
    }
    cout<< dp[w]<<endl;
    return 0;
}

01 背包优化

完全背包

在N种 物品取出若干件放在容量为W的背包里,每件物品的体积为W1,W2……Wn(Wi为整数),与之相对应的价值为P1,P2……Pn(Pi为整数)。求背包能够容纳的最大价值。

完全背包和01 背包的区别就是 能够存储的物品可以挑选多次

所以 转移方程也就变成了 dp[i][j] = max(dp[i-1][j] , dp[i][j-v[i]]+s[i]); // 不选 就是dp[i-1][j]  选就用dp[i][j-v[i]]+s[i]

//而01背包 就是dp[i][j] = max(dp[i-1][j] , dp[i-1][j-v[i]]+s[i])

#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;
const int maxn = 100 + 5;

int n ,w;
int v[maxn],s[maxn];
int dp[2][10010];

int main()
{
    cin>> n >> w;
    for(int i=1;i <= n;i++){
        cin >> v[i] >> s[i];
    }
    int now = 1,pre = 0;
    for(int i=1;i <= n;i++)
    {
        for(int j=0;j<=w;j++)
        {
            if(j < v[i])
                dp[now][j] = dp[pre][j];
            else
                dp[now][j] = max(dp[pre][j] , dp[now][j-v[i]]+s[i]); // 不选 就是dp[i-1][j]
                //选就是dp[i][j-v[i]]+s[i]
        }
        swap (now,pre);
    }
    cout<< dp[pre][w]<<endl;
    return 0;
}

完全背包

下面也是优化过的

#include <iostream>
#include <cstdio>
#include <cmath>
#include <string.h>
using namespace std;
const int maxn = 100 + 5;

int n ,w;
int v[maxn],s[maxn];
int dp[10010];

int main()
{
    cin>> n >> w;
    for(int i=1;i <= n;i++){
        cin >> v[i] >> s[i];
    }
    memset(dp,0,sizeof(dp));
    for(int i=1;i <= n;i++)
    {
        for(int j=v[i];j <= w;j++)//可以从上面一个状态转移 正着写 就能覆盖上次的计算了
            dp[j] = max(dp[j] , dp[j-v[i]]+s[i]);
    }
    cout<< dp[w]<<endl;
    return 0;
}

完全背包 优化

时间: 2024-10-16 03:06:42

背包问题 2017-7-24的相关文章

Becoming inspired - ASC - 2017 MARCH 24

Becoming inspired - The 11 questions to ask yourself when you feel uninspired @ Advanced Studio Classroom Vol: 2017 MARCH 24 Maybe you're struggling to find out what it is you care most about. Be struggling to.. To find out + what it is you care most

2017.12.24(查找最接近元素等)

2017.12.24  贪心,分治综合习题(2) 1.查找最接近元素 思路:由题可知,n<=100000,m<=10000,如果每一个m都把这个非降序序列扫一遍的话,那么时间复杂的将要到达1010那么多,明显不合题意:所以,只能用二分查找来优化时间复杂度. 核心代码: int left=1,right=n,mid,bz=0; while(left<right-1){ bz=0; mid=(left+right)/2; if(k==num[mid]){ printf("%d\n&

2017冬季24集训模拟-3.耀西岛

--------------------------题解 路径的长度是1-200000 然后路径的条数有n*(n+1)/2 根据鸽巢原理n*(n+1)/2 > 200000就一定是YES 所以复杂度只有n^2 1 #include <iostream> 2 #include <queue> 3 #include <set> 4 #include <cstdio> 5 #include <cstring> 6 #include <vec

2017冬季24集训模拟-1.寻找幽灵

--------------------------------------------题解 把最短路处理出来然后做背包 没有把head数组和all初始化qwq 1 #include <iostream> 2 #include <queue> 3 #include <set> 4 #include <cstdio> 5 #include <cstring> 6 #include <vector> 7 #include <algo

【2017 4 24 - B】 组合数

[题目描述] 输入格式: 一行一个正整数n 输出格式: 一行一个数f(n)对1000000007取余的值 [分析] 就是乱搞?? 就是问根到叶子有多少条路径嘛. 然后路径可以π.1.1.π...这样表示 枚举有多少个$π$,算出最后一个π前面最多多少个1[这样比较不容易算重复什么的],然后用组合数算一算. 有一个比较坑的地方就是比如3.2是-π是大于0但是是不能减的因为3.2已经小于4了. 然后就是假设枚举了i个π,最后一个π前面最多y个1. 就是 $\sum_{j=0}^{y} C_{i+j-

2017冬季24集训模拟-4.排座椅

--------------------题解 统计这一列或行放通道能隔开几个人,然后贪心 输出没有排序QWQ 1 #include <iostream> 2 #include <queue> 3 #include <set> 4 #include <cstdio> 5 #include <cstring> 6 #include <vector> 7 #include <algorithm> 8 #define siji(i

2017第24周日

生在哪里不重要,活成什么样才最重要.美貌终会衰老,而智慧.善良.勇气,会随着岁月的流逝,而历久弥新,化成你身上退之不去的魅力. 哈马德和第一任妻子,本来就有两个儿子,但是他还是不顾卡塔尔立储立长的传统,王位传给他和莫扎的儿子.真正的珍珠,不会被埋没,但首先,你得把自己磨砺成珍珠. 这是刚看到的莫扎的故事,从囚犯子女成长为倾国皇妃,从被人蔑视嘲笑到受到国人崇敬,她用自己的努力智慧行动改变了卡塔尔,造福万千国民,她是很多出身不幸的人应该学习的榜样. 周日618,京东购物节,但感觉很一般,远没有那么多

2017.3.24上午

R1(config)#router ospf 100     进入OSPF进程,后面的100是进程号 R1(config-router)#net 1.1.1.0 0.0.0.255 area 0 宣告1.1.1.0/24的网段,后面area区域为0,也就是宣告进入到骨干区域"0"中. R1(config-router)#net 199.99.1.0 0.0.0.255 area 0 宣告199.99.1.0/24的网段,后面area区域为0,也就是宣告进入到骨干区域"0&qu

2017.09.24校内训练

T1:个人卫生综合征 题目描述: 每天BBS都要从家里经过城市中的一段路到学校刷五三.城市中一共有n个路口和m条双向道路,每条双向道路都连接着两个路口ai.bi且有一定的时间花费vi.BBS家编号为1,学校编号为n.今天,BBS由于个人卫生综合征导致他很迟才离开家,他想用膜法改变k条道路的长度使通过其的时间花费vi变为0.现在他问你改变道路长度之后他到学校的最小时间花费是多少? 输入格式: 第一行为三个整数n.m.k,接下来的m行每行三个整数ai,bi,vi,分别表示这条路连着的两个路口和通过其

【第二组】项目冲刺(Beta版本)第六次每日例会 2017/7/24

项目冲刺(Beta版本)第六次每日例会 开发小组:Hunter 冲刺经理:林贵渊 小组成员:林轩宇,张太,李明君,刘仁人 1.每日例会内容 (1)昨天做了什么 1.林轩宇:Button音效及服务器相关内容. 2.刘仁人:二维码制作. 3.张太:查找本地内容. 4.李明君:LOGO设计,Button美化. 5.林贵渊:本地内容整理优化. (2)遇到了什么问题 1.图像传输问题(林轩宇) 2.部分功能存在一些小BUG(李明君,林贵渊) 3.控件及界面优化(刘仁人,李明君) 4.玩家交互没有好的构想[