ZOJ1366经典dp(多重背包转01背包+优化空间)


 1  //zoj1366类似背包的问题
2 //争取一遍AC
3 #include<iostream>
4 #include<string.h>
5 #include<stdio.h>
6 #define maxn 13
7 using namespace std;
8
9 int k[maxn];
10 int n1[maxn];
11 int c1[maxn];
12 int c2[105];
13 int dp[110000];
14 int Cash,N1,N2;
15 void solve1(){
16 N2=0;
17 for(int i=1;i<=N1;i++){
18 int now=n1[i];
19 for(int a=1;a<=now;a=a*2){
20 if (now>=a){
21 c2[++N2]=a*c1[i];
22 now=now-a;
23 }
24 }
25 if (now>0){
26 c2[++N2]=now*c1[i];
27 }
28 }
29 }
30 int main(){
31 while(~scanf("%d%d",&Cash,&N1)){
32 for(int i=1;i<=N1;i++) scanf("%d%d",&n1[i],&c1[i]);
33 solve1();
34 memset(dp,0,sizeof(dp));
35 dp[0]=1;
36 for(int i=1;i<=N2;i++){
37 for(int v=Cash;v>=0;v--){
38 if (v<c2[i]) dp[v]=dp[v];
39 else {
40 if (dp[v-c2[i]]) dp[v]=1;
41 }
42 // if (dp[v])cout<<"i"<<i<<","<<v<<endl;
43 }
44 }
45 int ans=0;
46 for(int v=0;v<=Cash;v++) if (dp[v])ans=max(ans,v);
47 cout<<ans<<endl;
48
49 }
50 return 0;
51 }

容易错误:用数组空间用数字定义不容易弄错,

分解是按照1,2,4,8....的顺序来的

可以写成搜索(要好好研究这个方法,比如这个:http://vjudge.net/problem/viewSource.action?id=95777),可以尝试排序优化搜索的方法

题解:

多重背包分解成01背包+滚动数组优化空间

时间: 2024-10-11 00:44:40

ZOJ1366经典dp(多重背包转01背包+优化空间)的相关文章

多重背包转换成完全背包和01背包

void CompletePack(int cost,int weight)   多重背包 { for(int i=cost;i<=m;i++) dp[i]=max(dp[i],dp[i-cost]+weight); } void ZeroOnePack(int cost,int weight)    01背包 { for(int i=m;i>=cost;i--) dp[i]=max(dp[i],dp[i-cost]+weight); } void MultiplyPack(int cost,

背包之01背包、完全背包、多重背包详解

首先说下动态规划,动态规划这东西就和递归一样,只能找局部关系,若想全部列出来,是很难的,比如汉诺塔.你可以说先把除最后一层的其他所有层都移动到2,再把最后一层移动到3,最后再把其余的从2移动到3,这是一个直观的关系,但是想列举出来是很难的,也许当层数n=3时还可以模拟下,再大一些就不可能了,所以,诸如递归,动态规划之类的,不能细想,只能找局部关系. 1.汉诺塔图片 (引至杭电课件:DP最关键的就是状态,在DP时用到的数组时,也就是存储的每个状态的最优值,也就是记忆化搜索) 要了解背包,首先得清楚

#1038 : 01背包 ( 01 背包,基础DP)

#1038 : 01背包 时间限制:20000ms 单点时限:1000ms 内存限制:256MB 描述 且说上一周的故事里,小Hi和小Ho费劲心思终于拿到了茫茫多的奖券!而现在,终于到了小Ho领取奖励的时刻了! 小Ho现在手上有M张奖券,而奖品区有N件奖品,分别标号为1到N,其中第i件奖品需要need(i)张奖券进行兑换,同时也只能兑换一次,为了使得辛苦得到的奖券不白白浪费,小Ho给每件奖品都评了分,其中第i件奖品的评分值为value(i),表示他对这件奖品的喜好值.现在他想知道,凭借他手上的这

背包整理(01背包,完全背包,多重背包,分组背包)(待更新)

目录 01背包 优化(空间) 完全背包 优化 多重背包 优化 分组背包 01背包 有N件物品和一个容量为V的背包.第i件物品的价格(即体积,下同)是w[i],价值是c[i].求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和最大. 对于每个物品,我们有两种选择:把这个物品放进背包还是不放. d[i][v]表示前i件物品,恰放入容积为v的背包时的价值总和. 状态转移方程为 \[d[i][v] = \max(d[i - 1][v],d[i - 1][v - w[i]] + c[i

POJ1276 多重背包(01背包 完全背包)

POJ1276 题目 多重背包模板题,给定背包容量\(V\),给定\(N\)种物品,每种物品的个数\(n_i\).体积\(v_i\)和重量\(w_i\)已知,求背包能装下的物品的最大重量.对应本题就是,给定提款的金额cash,给定\(N\)种钱币,每种钱币的个数为\(n_i\).面额\(D_i\)已知,求能兑换的钱币的最大值.本题中,体积和重量都等于面额. Sample Input 735 3 4 125 6 5 3 350 633 4 500 30 6 100 1 5 0 1 735 0 0

HDU 3033 I love sneakers! 我爱运动鞋 (分组背包,01背包,严重变形)

题意:给出k家店,每家店内有各种价格的鞋子(同样的鞋子只能买一双),每双鞋子有价值,要求每家店至少买一双.给出m钱,求获得的最大价值. 思路:分组背包严重变形了,变成了相反的,每组物品至少挑1件(分组背包是至多挑1件).虽然是分组背包的变形,但是用到的却是01背包的思路.要求每家店至少买1双,那么可以只买一双双,也可以买多双.难点在这.需要维护两行dp状态值即可.第一行是前面组的物品的最佳状态,第二行是第i件物品之前的最佳状态(已经装进同组物品). 对于i组第t件物品,(1)要么从i组之前的状态

Big Event in HDU(背包九讲_多重背包转01背包)

Big Event in HDUCrawling in process... Crawling failed Time Limit:5000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit Status Description Nowadays, we all know that Computer College is the biggest department in HDU. But, maybe you

Re0:DP学习之路 01背包如何打印路径?

伪代码 用二维数组记录,如果出现可以转移的dp那么记录bk[当前体积][装的物品]=1 输出的时候倒推,如果存在连通的边那么输出并且总共的体积减去输出的体积 代码(uva-624,目前wa不明所以,网上的答案也是那么输出的,或许要输出最多的物品?目前也不会这种玩法) #include <bits/stdc++.h> using namespace std; int v[1000],dp[1000000],bk[1000][1000]; int main() { ios::sync_with_s

c++01背包一维数组版及java多重背包

#include<bits/stdc++.h> #define ll long long using namespace std; const int maxn=1010; int c[maxn],w[maxn]; int dp[maxn]; int main(){ int n,v; cin>>n>>v; for(int i=1;i<=n;i++) cin>>c[i]; for(int i=1;i<=n;i++) cin>>w[i];