C++ 算法篇 动态规划----背包

一、01背包

题目:有 N 件物品和一个容量为 V 的背包。第 i 件物品的费用是 w[i],价值是 p[i]。求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和最大。  

  例,有3个物品,背包容量为10,如下:

 二维解法:

#include
using namespace std;
int f[50][220]={0},w[40],p[40];
int main()
{  int i,v,V,n;
   cin>>V>>n;
   for(i=1;i<=n;i++)
      cin>>w[i]>>p[i];
   for(i=1;i<=n;i++)
   { for(v=V;v>=1;v--)
       if(v

 初始时:我们初始化f[]全部为0

  第1次主循环,即当i = 1时,我们只对物品1进行选择,对于内层循环,即当v = 10....3时,我们有:

  f[10] = max{f[10], f[10-3]+p[1]} = max{f[10], f[7]+4} = max{0, 0+4} = 4;

  f[9] = max{f[9], f[9-3]+p[1]} = max{f[9], f[6]+4} = max{0, 0+4} = 4;

  f[8] =max{f[8], f[8-3]+p[1]} = max{f[8], f[5]+4} = max{0, 0+4} = 4;

  f[7] = max{f[7], f[7-3]+p[1]} = max{f[7], f[4]+4} = max{0, 0+4} = 4;

  f[6] = max{f[6], f[6-3]+p[1]} = max{f[6], f[3]+4} = max{0, 0+4} = 4;

  f[5] = max{f[5], f[5-3]+p[1]} = max{f[5], f[2]+4} = max{0, 0+4} = 4;

  f[4] = max{f[4], f[4-3]+p[1]} = max{f[4], f[1]+4} = max{0, 0+4} = 4;

  f[3] = max{f[3], f[3-3]+p[1]} = max{f[3], f[0]+4} = max{0, 0+4} = 4;

  f[2] = f[1] = f[0] = 0;

  其中f[2] = f[1] = f[0] = 0,是因为体积为3的物品,根本不会影响当背包容量为2、1、0时的状态。所以他们依旧保持原来的状态。对应于:

  表中横轴的蓝色区域,表示当容量为v时,对第1个商品做出选择时所依赖的上一层的状态,如当v=10时,所依赖的就是f[0][10]和f[0][7]两个状态。所以当计算f[1][v](v = 10....3)时,f[v]和[v-3]保存的就是f[0][v]和f[0][v-3]。

  第2次循环,即i = 2时,我们对物品2做出选择:

  f[10] = max{f[10], f[10-4]+p[2]} = max{f[10], f[6]+p[2]} = max{4, 4+5} = 9

  f[9] = max{f[9], f[9-4]+p[2]} = max{f[9], f[5]+p[2]} = max{4, 4+5} = 9

  f[8] = max{f[8], f[8-4]+p[2]} = max{f[8], f[4]+p[2]} = max{4, 4+5} = 9

  f[7] = max{f[7], f[7-4]+p[2]} = max{f[7], f[3]+p[2]} = max{4, 4+5} = 9

  f[6] = max{f[6], f[6-4]+p[2]} = max{f[6], f[2]+p[2]} = max{4, 0+5} = 5

  f[5] = max{f[5], f[5-4]+p[2]} = max{f[5], f[1]+p[2]} = max{4, 0+5} = 5

  f[4] = max{f[4], f[4-4]+p[2]} = max{f[4], f[0]+p[2]} = max{4, 0+5} = 5

  f[3] = 4

  f[2] = f[1] = f[0] = 0;

  第3次循环,即当i = 3时

  f[10] = max{f[10], f[10-5]+p[3]} = max{f[10], f[5]+3} = max{9, 5+6} = 11

  f[9] = max{f[9], f[9-5]+p[3]} = max{f[9], f[4]+3} = max{9, 5+6} = 11

  f[8] = max{f[8], f[8-5]+p[3]} = max{f[8], f[3]+3} = max{9, 4+6} = 10

  f[7] = max{f[7], f[7-5]+p[3]} = max{f[7], f[2]+3} = max{9, 0+6} = 9

  f[6] = max{f[6], f[6-5]+p[3]} = max{f[6], f[1]+3} = max{5, 0+6} = 6

  f[5] = max{f[5], f[5-5]+p[3]} = max{f[5], f[0]+3} = max{5, 0+6} = 6

  f[4] = 5

  f[3] = 4

  f[2] = f[1] = f[0]

  对于应表:

   如果还是疑问为什么v从小到大的顺序不可以(即内循环为:for(int v = w[i]; v <= V; ++v)),我们依旧可以按着代码,试着画一下表,一次,就很清楚了,比如同样的问题,正着走一次为:

  当i=1时:

  f[0] = f[1] = f[2] = 0

  f[3] = max{f[3], f[3-3]+p[1]} = max{0, 0+4} = 4

  f[4] = max{f[4], f[4-3]+p[1]} = max{0, 0+4} = 4

  f[5] = max{f[5], f[5-3]+p[1]} = max{0, 0+4} = 4

  以上结果貌似是对的,但是意思已经完全不是我们当初设计代码时的思想了,注意下面:

  f[6] = max{f[6], f[6-3]+p[1]} = max{0. 4+4} = 8//此时我们用的f[6]和f[3]相当于是f[1][6]和f[1][3],而不是f[0][6]和f[0][3]!

  f[7] = max{f[7], f[7-3]+p[1]} = max{0, 4+4} = 8

  f[8] = max{f[8], f[8-3]+p[1]} = max{0, 4+4} = 8

  f[9] = max{f[9], f[9-3]+p[1]} = max{0, 8+4} = 12

  f[10] = max{f[10], f[10-3]+p[1]} = max{0, 8+4} = 12

  到此,我们清楚了为什么正向循环为何不可,因为此时f[v]保存的相当于是f[i][v]和f[i][v-w[i]],这已经违背了我们意图!

 

一维解法:

综上的步骤我们可以很清楚的知道v从大到小循环可以满足题意,从表中我们也可以知道,我们如用f[i][v]存储最优结果,有很多没用的求解结果也被保存下来,从而浪费了大量的空间。如果我们用f[v],那么保存的就是最终结果,且很好地利用了空间。

#include
using namespace std;
int f[220]={0},w[40],p[40];
int main()
{  int i,v,V,n;
   cin>>V>>n;
   for(i=1;i<=n;i++)
      cin>>w[i]>>p[i];
   for(i=1;i<=n;i++)
   { for(v=V;v>=w[i];v--)
       f[v]=max(f[v],f[v-w[i]]+p[i]); 
     //for(v=1;v<=V;v++) cout<

练习:

1、P1048 采药
题目描述
辰辰是个天资聪颖的孩子,他的梦想是成为世界上最伟大的医师。为此,他想拜附近最有威望的医师为师。医师为了判断他的资质,给他出了一个难题。医师把他带到一个到处都是草药的山洞里对他说:“孩子,这个山洞里有一些不同的草药,采每一株都需要一些时间,每一株也有它自身的价值。我会给你一段时间,在这段时间里,你可以采到一些草药。如果你是一个聪明的孩子,你应该可以让采到的草药的总价值最大。”如果你是辰辰,你能完成这个任务吗?

输入格式
第一行有2个整数T(1≤T≤1000)和M(1≤M≤100),用一个空格隔开,T代表总共能够用来采药的时间,M代表山洞里的草药的数目。
接下来的M行每行包括两个在1到100之间(包括1和100)的整数,分别表示采摘某株草药的时间和这株草药的价值。

输出格式
1个整数,表示在规定的时间内可以采到的草药的最大总价值。

输入输出样例
输入
70 3
71 100
69 1
1    2
输出 
3
说明/提示
对于30%的数据,M≤10;

对于全部的数据,M≤100

NOIP2005普及组第三题

 

2、P2871 [USACO07DEC]手链Charm Bracelet
题目描述
有N件物品和一个容量为V的背包。第i件物品的重量是c[i],价值是w[i]。求解将哪些物品装入背包可使这些物品的重量总和不超过背包容量,且价值总和最大。
输入格式

第一行:物品个数N和背包大小M

第二行至第N+1行:第i个物品的重量C[i]和价值W[i]

输出格式

输出一行最大价值。

输入输出样例
输入 
4 6
1 4
2 6
3 12
2 7
输出 
23

3、P1060 开心的金明

题目描述:金明今天很开心,家里购置的新房就要领钥匙了,新房里有一间他自己专用的很宽敞的房间。更让他高兴的是,妈妈昨天对他说:“你的房间需要购买哪些物品,怎么布置,你说了算,只要不超过N元钱就行”。今天一早金明就开始做预算,但是他想买的东西太多了,肯定会超过妈妈限定的N元。于是,他把每件物品规定了一个重要度,分为5等:用整数1−5表示,第5等最重要。他还从因特网上查到了每件物品的价格(都是整数元)。他希望在不超过N元(可以等于N元)的前提下,使每件物品的价格与重要度的乘积的总和最大。

设第j件物品的价格为v[​j],重要度为w[​j],共选中了k件物品,编号依次为j1​,j2​,…,jk​,则所求的总和为:

v[​j1​]×w[​j1​]+v[​j2​]×w[​j2​]+…+v[​jk​]×w[​jk​]。

请你帮助金明设计一个满足要求的购物单。

输入格式

第一行,为2个正整数,用一个空格隔开:Nm(其中N(<30000)表示总钱数,m(<25)为希望购买物品的个数。)

从第2行到第m+1行,第jj行给出了编号为j−1的物品的基本数据,每行有2个非负整数vp(其中v表示该物品的价格(v≤10000),p表示该物品的重要度(1−5)

输出格式

1个正整数,为不超过总钱数的物品的价格与重要度乘积的总和的最大值(<100000000)。

输入输出样例

输入 

1000 5
800 2
400 5
300 5
400 3
200 2

输出 

3900

说明/提示

NOIP 2006 普及组 第二题

4、最大约数和
题目描述
选取和不超过S的若干个不同的正整数,使得所有数的约数(不含它本身)之和最大。

输入格式
输入一个正整数S。

输出格式
输出最大的约数之和。

输入输出样例
输入 
11
输出 
9
说明/提示
样例说明:取数字4和6,可以得到最大值(1+2)+(1+2+3)=9。
数据规模:S<=1000
 

P1510 精卫填海

【问题描述】

发鸠之山,其上多柘木。有鸟焉,其状如乌,文首,白喙,赤足,名曰精卫,其名自詨。是炎帝之少女,名曰女娃。女娃游于东海,溺而不返,故为精卫。常衔西山之木石,以堙于东海。——《山海经》

精卫终于快把东海填平了!只剩下了最后的一小片区域了。同时,西山上的木石也已经不多了。精卫能把东海填平吗?

事实上,东海未填平的区域还需要至少体积为v的木石才可以填平,而西山上的木石还剩下n块,每块的体积和把它衔到东海需要的体力分别为k和m。精卫已经填海填了这么长时间了,她也很累了,她还剩下的体力为c。

输入格式

输入文件的第一行是三个整数:v、n、c。

从第二行到第n+1行分别为每块木石的体积和把它衔到东海需要的体力。

输出格式

输出文件只有一行,如果精卫能把东海填平,则输出她把东海填平后剩下的最大的体力,否则输出’Impossible’(不带引号)。

输入输出样例

输入 

100 2 10
50 5
50 5

输出 

0

输入

10 2 1
50 5
10 2

输出

Impossible

说明/提示

【数据范围】

对于20%的数据,0

对于50%的数据,0

对于100%的数据,0

 

 

二、完全背包

【问题描述】设有n种物品,每种物品有一个重量及一个价值。但每种物品的数量是无限的,同时有一个背包,最大载重量为M,今从n种物品中选取若干件(同一种物品可以多次选取),使其重量的和小于等于M,而价值的和为最大。

【输入格式】

第一行:两个整数,M(背包容量,M<=200)和N(物品数量,N<=30);

第2..N+1行:每行二个整数Wi,Ci,表示每个物品的重量和价值。

【输出格式】

仅一行,一个数,表示最大总价值。

【样例输入】

10  4
2  1
3  3
4  5
7  9  9

【样例输出】

max=12

#include
using namespace std;
int f[220]={0},w[40],c[40];
int main()
{  int i,m,M,n;
   cin>>M>>n;
   for(i=1;i<=n;i++)
      cin>>w[i]>>c[i];
   for(i=1;i<=n;i++)
   { for(m=w[i];m<=M;m++)
      f[m]= max(f[m],f[m-w[i]]+c[i]); 
	 //for(m=1;m<=M;m++) cout<

第一次循环:

重量 价值 物品 0 1 2 3 4 5 6 7 8 9 10
0 0 0 0 0 0 0 0 0 0 0 0 0 0
2 1 1 0 0 1 1 2 2 3 3 4 4 5
3 3 2 0 0                  
4 5 3 0 0                  
7 9 4 0 0                  

其中 f[1] = f[0] = 0,是因为重量为2的物品,根本不会影响当背包容量为1、0时的状态。所以他们依旧保持原来的状态。对应于:f[1] = f[0] = 0;第1次主循环,即当i = 1时,我们只对物品1进行选择,对于内层循环,即当v =2....10时,我们有:

f[2] = max{f[2], f[2-2]+c[1]} = max{f[2], f[0]+1} = max{0, 0+1} = 1;

f[3] = max{f[3], f[3-2]+c[1]} = max{f[3], f[1]+1} = max{0, 0+1} = 1;

f[4] = max{f[4], f[4-2]+c[1]} = max{f[4], f[2]+1} = max{0, 1+1} = 2;

f[5] = max{f[5], f[5-2]+c[1]} = max{f[5], f[3]+1} = max{0, 1+1} = 2;

f[6] = max{f[6], f[6-2]+c[1]} = max{f[6], f[4]+1} = max{0, 2+1} =3;

f[7] = max{f[7], f[7-2]+c[1]} = max{f[7], f[5]+1} = max{0, 2+1} = 3;

f[8] = max{f[8], f[8-2]+c[1]} = max{f[8], f[6]+1} = max{0, 3+1} = 4;

f[9] = max{f[9], f[9-2]+c[1]} = max{f[9], f[7]+1} = max{0, 3+1} = 4;

f[10] = max{f[10], f[10-2]+c[1]} = max{f[10], f[8]+1} = max{0, 4+1} = 5;

第二次循环:

重量 价值 物品 0 1 2 3 4 5 6 7 8 9 10
0 0 0 0 0 0 0 0 0 0 0 0 0 0
2 1 1 0 0 1 1 2 2 3 3 4 4 5
3 3 2 0 0 1 3 3 4 6 6 7 9 9
4 5 3 0 0                  
7 9 4 0 0                  

第2次主循环,即当i = 2时,我们只对物品2进行选择,对于内层循环,即当v =3....10时,我们有:

其中 f[1] = f[0] = 0,是因为重量为3的物品,根本不会影响当背包容量为0、1、2时的状态。所以他们依旧保持原来的状态。对应于:f[1] = f[0] = 0,f[2]=1;

f[3] = max{f[3], f[3-3]+c[2]} = max{f[3], f[0]+3} = max{1, 0+3} = 3;

f[4] = max{f[4], f[4-3]+c[2]} = max{f[4], f[1]+3} = max{2, 0+3} = 3;

f[5] = max{f[5], f[5-3]+c[2]} = max{f[5], f[2]+3} = max{2, 1+3} = 4;

f[6] = max{f[6], f[6-3]+c[2]} = max{f[6], f[3]+3} = max{3, 3+3} =6;

f[7] = max{f[7], f[7-3]+c[2]} = max{f[7], f[4]+3} = max{3, 3+3} = 6;

f[8] = max{f[8], f[8-3]+c[2]} = max{f[8], f[5]+3} = max{4, 4+3} = 7;

f[9] = max{f[9], f[9-3]+c[2]} = max{f[9], f[6]+3} = max{4, 6+3} = 9;

f[10] = max{f[10], f[10-3]+c[2]} = max{f[10], f[7]+3} = max{5, 6+3} = 9;

第三次循环:

重量 价值 物品 0 1 2 3 4 5 6 7 8 9 10
0 0 0 0 0                  
2 1 1 0 0                  
3 3 2 0 0 1 3 3 4 6 6 7 9 9
4 5 3 0 0 1 3 5 5 6 8 10 10 11
7 9 4 0 0                  

第3次主循环,即当i = 3时,我们只对物品3进行选择,对于内层循环,即当v =4....10时,我们有:

其中 f[1] = f[0] = 0,是因为重量为4的物品,根本不会影响当背包容量为0、1、2、3时的状态。所以他们依旧保持原来的状态。对应于:f[1] = f[0] = 0,f[2]=1,f[3]=3;

f[4] = max{f[4], f[4-4]+c[3]} = max{f[4], f[0]+5} = max{3, 0+5} = 5;

f[5] = max{f[5], f[5-4]+c[3]} = max{f[5], f[1]+5} = max{4, 0+5} = 5;

f[6] = max{f[6], f[6-4]+c[3]} = max{f[6], f[2]+5} = max{6, 1+5} =6;

f[7] = max{f[7], f[7-4]+c[3]} = max{f[7], f[3]+5} = max{6, 3+5} = 8;

f[8] = max{f[8], f[8-4]+c[3]} = max{f[8], f[4]+5} = max{7, 5+5} = 10;

f[9] = max{f[9], f[9-4]+c[3]} = max{f[9], f[5]+5} = max{9, 5+5} = 10;

f[10] = max{f[10], f[10-4]+c[3]} = max{f[10], f[6]+5} = max{9, 6+5} = 11;

第四次循环:

重量 价值 物品 0 1 2 3 4 5 6 7 8 9 10
0 0 0 0 0                  
2 1 1 0 0                  
3 3 2 0 0                  
4 5 3 0 0 1 3 5 5 6 8 10 10 11
7 9 4 0 0 1 3 5 5 6 9 10 10 12

第4次主循环,即当i = 4时,我们只对物品4进行选择,对于内层循环,即当v =7....10时,我们有:

因为重量为7的物品,根本不会影响当背包容量为0、1、2、3、4、5、6时的状态。所以他们依旧保持原来的状态。对应于:f[1] = f[0] = 0,f[2]=1,f[3]=3,f[4]=5,  f[5]=5,  f[6]=6;

f[7] = max{f[7], f[7-7]+c[4]} = max{f[7], f[0]+9} = max{8, 0+9} = 9;

f[8] = max{f[8], f[8-7]+c[4]} = max{f[8], f[1]+9} = max{10, 9} = 10;

f[9] = max{f[9], f[9-7]+c[4]} = max{f[9], f[2]+9} = max{10, 1+9} = 10;

f[10] = max{f[10], f[10-7]+c[4]} = max{f[10], f[3]+9} = max{11, 3+9} = 12;

 

练习:

1、总分

时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 32768K,其他语言65536K

题目描述:学生在我们USACO的竞赛中的得分越多我们越高兴。我们试着设计我们的竞赛以便人们能尽可能的多得分,这需要你的帮助。我们可以从几个种类中选取竞赛的题目,这里的一个"种类"是指一个竞赛题目的集合,解决集合中的题目需要相同多的时间并且能得到相同的分数你的任务是写一个程序来告诉USACO的职员,应该从每一个种类中选取多少题目,使得解决题目的总耗时在竞赛规定的时间里并且总分最大。
输入包括竞赛的时间,M(1 <= M <= 10,000)(不要担心,你要到了训练营中才会有长时间的比赛)和N,"种类"的数目1 <= N <= 10,000。
后面的每一行将包括两个整数来描述一个"种类":
第一个整数说明解决这种题目能得的分数(1 <= points <= 10000),第二整数说明解决这种题目所需的时间(1 <= minutes <= 10000)。
你的程序应该确定我们应该从每个"种类"中选多少道题目使得能在竞赛的时间中得到最大的分数。
来自任意的"种类"的题目数目可能任何非负数(0或更多)。
计算可能得到的最大分数

输入描述:

第 1行:M,N--竞赛的时间和题目"种类"的数目。
第 2-N+1 行:两个整数:每个"种类"题目的分数和耗时。

输出描述:

单独的一行包括那个在给定的限制里可能得到的最大的分数。

输入

300 4
100 60
250 120
120 100
35 20

输出

605

说明

{从第2个"种类"中选两题第4个"种类"中选三题}

2、郭嘉烜送礼(一)

时间限制:C/C++ 5秒,其他语言10秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld

题目描述:郭嘉烜现在在给女朋友挑礼物,以提升女朋友对他的好感度。商店里有n种礼物,他们的库存都是无限的。第i种礼物能够提升女朋友对他的好感度v[i],第i种礼物的价格为w[i],现在郭嘉烜只有c元,问他应该挑选哪些礼物来使得女朋友对他的好感度提升最多。

输入描述:

第一行包括两个整数n、c。

接下来n行,每行2个数,表示表示第i种礼物能够提升女朋友对他的好感度v[i]与第i种礼物的价格w[i]。

输出描述:

一行。一个整数,表示最多能提升的好感度。

输入

2 2
1 1
2 1

输出

4

备注:

1<=n,c<=1000,1<=v[i],w[i]<=100

3、P1853 投资的最大效益

题目背景

约翰先生获得了一大笔遗产,他暂时还用不上这一笔钱,他决定进行投资以获得更大的效益。银行工作人员向他提供了多种债券,每一种债券都能在固定的投资后,提供稳定的年利息。当然,每一种债券的投资额是不同的,一般来说,投资越大,收益也越大,而且,每一年还可以根据资金总额的增加,更换收益更大的债券。

题目描述

例如:有如下两种不同的债券:①投资额4000,年利息400;②投资额3000,年利息250。初始时,有10000的总资产,可以投资两份债券①债券,一年获得10000的总资产,可以投资两份债券①债券,一年获得800的利息;而投资一份债券①和两份债券②,一年可获得900的利息,两年后,可获得900的利息,两年后,可获得1800的利息;而所有的资产达到11800,然后将卖掉一份债券②,换购债券①,年利息可达到11800,然后将卖掉一份债券②,换购债券①,年利息可达到1050;第三年后,总资产达到12850,可以购买三份债券①,年利息可达到12850,可以购买三份债券①,年利息可达到1200,第四年后,总资产可达到$14050。

现给定若干种债券、最初的总资产,帮助约翰先生计算,经过n年的投资,总资产的最大值。

输入格式

第一行为三个正整数s,n,d,分别表示最初的总资产、年数和债券的种类。

接下来d行,每行表示一种债券,两个正整数a,b分别表示债券的投资额和年利息。

输出格式

仅一个整数,表示n年后的最大总资产。

输入输出样例

输入

10000 4 2
4000 400
3000 250

输出 

14050

说明/提示

s≤10^6,n≤40,d≤10,a≤10^4,且a是1000的倍数,b不超过a的10%。

 

4、P2563 [AHOI2001]质数和分解

题目描述

任何大于 1 的自然数 n 都可以写成若干个大于等于 2 且小于等于 n 的质数之和表达式(包括只有一个数构成的和表达式的情况),并且可能有不止一种质数和的形式。例如,9 的质数和表达式就有四种本质不同的形式:

9 = 2 + 5 + 2 = 2 + 3 + 2 + 2 = 3 + 3 + 3 = 2 + 7 。

这里所谓两个本质相同的表达式是指可以通过交换其中一个表达式中参加和运算的各个数的位置而直接得到另一个表达式。

试编程求解自然数 n 可以写成多少种本质不同的质数和表达式。

输入格式

文件中的每一行存放一个自然数 n(2 < n < 200) 。

输出格式

依次输出每一个自然数 n 的本质不同的质数和表达式的数目。

输入输出样例

输入

2

200

输出 

1
9845164

 

5、P5662 纪念品

题目描述

小伟突然获得一种超能力,他知道未来 T天 N 种纪念品每天的价格。某个纪念品的价格是指购买一个该纪念品所需的金币数量,以及卖出一个该纪念品换回的金币数量。每天,小伟可以进行以下两种交易无限次

  1. 任选一个纪念品,若手上有足够金币,以当日价格购买该纪念品;
  2. 卖出持有的任意一个纪念品,以当日价格换回金币。

每天卖出纪念品换回的金币可以立即用于购买纪念品,当日购买的纪念品也可以当日卖出换回金币。当然,一直持有纪念品也是可以的。T 天之后,小伟的超能力消失。因此他一定会在第 T天卖出所有纪念品换回金币。小伟现在有 M 枚金币,他想要在超能力消失后拥有尽可能多的金币。

输入格式

第一行包含三个正整数 T,N,M,相邻两数之间以一个空格分开,分别代表未来天数 T,纪念品数量 N,小伟现在拥有的金币数量 M。

接下来 T 行,每行包含 N 个正整数,相邻两数之间以一个空格分隔。第 i 行的 N 个正整数分别为 Pi,1​,Pi,2​,……,Pi,N​,其中 Pi,j​ 表示第 i天第 j种纪念品的价格。

输出格式

输出仅一行,包含一个正整数,表示小伟在超能力消失后最多能拥有的金币数量。

输入输出样例

输入 

6 1 100
50
20
25
20
25
50

输出 

305

输入 

3 3 100
10 20 15
15 17 13
15 25 16

输出 

217

说明/提示

【输入输出样例 1 说明】

最佳策略是:

第二天花光所有 100 枚金币买入 5 个纪念品 1;

第三天卖出 5 个纪念品 1,获得金币 125 枚;

第四天买入 6 个纪念品 1,剩余 5 枚金币;

第六天必须卖出所有纪念品换回 300 枚金币,第四天剩余 5 枚金币,共 305 枚金币。

超能力消失后,小伟最多拥有 305 枚金币。

【输入输出样例 2 说明】

最佳策略是:

第一天花光所有金币买入 10 个纪念品 1;

第二天卖出全部纪念品 1 得到 150 枚金币并买入 8 个纪念品 2 和 1 个纪念品 3,剩余 1 枚金币;

第三天必须卖出所有纪念品换回216 枚金币,第二天剩余1枚金币,共 217 枚金币。

超能力消失后,小伟最多拥有 217 枚金币。

【数据规模与约定】

对于 10% 的数据,T=1。

对于 30% 的数据,T≤4,N≤4,M≤100,所有价格 10≤Pi,j​≤100。

另有 15% 的数据,T≤100,N=1。

另有 15% 的数据,T=2,N≤100。

对于 100% 的数据,T≤100,N≤100,M≤103,所有价格 1≤Pi,j​≤104,数据保证任意时刻,小明手上的金币数不可能超过 10^4。

 

6、P1877 [HAOI2012]音量调节

时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K

题目描述:一个吉他手准备参加一场演出。他不喜欢在演出时始终使用同一个音量,所以他决定每一首歌之前他都要改变一次音量。在演出开始之前,他已经做好了一个列表,里面写着在每首歌开始之前他想要改变的音量是多少。每一次改变音量,他可以选择调高也可以调低。

音量用一个整数描述。输入文件中给定整数beginLevel,代表吉他刚开始的音量,以及整数maxLevel,代表吉他的最大音量。音量不能小于0也不能大于maxLevel。输入文件中还给定了n个整数c1,c2,c3…..cn,表示在第i首歌开始之前吉他手想要改变的音量是多少。

吉他手想以最大的音量演奏最后一首歌,你的任务是找到这个最大音量是多少。

输入描述:

第一行依次为三个整数:n, beginLevel, maxlevel。

第二行依次为n个整数:c1,c2,c3…..cn。

输出描述:

输出演奏最后一首歌的最大音量。如果吉他手无法避免音量低于0或者高于maxLevel,输出-1。

输入

3 5 10
5 3 7

输出10

 

7、P2918 [USACO08NOV]买干草Buying Hay

约翰的干草库存已经告罄,他打算为奶牛们采购H(1 \leq H \leq 50000)H(1≤H≤50000)镑干草.

他知道N(1 \leq N\leq 100)N(1≤N≤100)个干草公司,现在用11到NN给它们编号.第ii公司卖的干草包重量 为P_i (1 \leq P_i \leq 5,000)Pi​(1≤Pi​≤5,000) 磅,需要的开销为C_i (1 \leq C_i \leq 5,000)Ci​(1≤Ci​≤5,000) 美元.每个干草公司的货源都十分充足, 可以卖出无限多的干草包.

帮助约翰找到最小的开销来满足需要,即采购到至少HH镑干草.

输入格式

* Line 1: Two space-separated integers: N and H

* Lines 2..N+1: Line i+1 contains two space-separated integers: P_i and C_i

输出格式

* Line 1: A single integer representing the minimum cost FJ needs to pay to obtain at least H pounds of hay.

输入输出样例

输入 

2 15 
3 2 
5 3 

输出 

9 

 

 

三、多重背包

 

 

四、混合背包

11、 樱花

题目描述:爱与愁大神后院里种了n棵樱花树,每棵都有美学值Ci。爱与愁大神在每天上学前都会来赏花。爱与愁大神可是生物学霸,他懂得如何欣赏樱花:一种樱花树看一遍过,一种樱花树最多看Ai遍,一种樱花树可以看无数遍。但是看每棵樱花树都有一定的时间Ti。爱与愁大神离去上学的时间只剩下一小会儿了。求解看哪几棵樱花树能使美学值最高且爱与愁大神能准时(或提早)去上学。

输入格式

共n+1行:

第1行:三个数:现在时间Ts(几点:几分),去上学的时间Te(几点:几分),爱与愁大神院子里有几棵樱花树n。

第2行~第n+1行:每行三个数:看完第i棵树的耗费时间Ti,第i棵树的美学值Ci,看第i棵树的次数Pi(Pi=0表示无数次,Pi是其他数字表示最多可看的次数Pi)。

输出格式

只有一个整数,表示最大美学值。

输入输出样例

输入 

6:50 7:00 3
2 1 0
3 3 1
4 5 4

输出 

11

说明/提示

100%数据:Te-Ts ≤ 1000,n ≤ 10000

样例解释:赏第一棵樱花树一次,赏第三棵樱花树2次

 

 

五、分组背包

1、通天之分组背包

题目背景

直达通天路·小A历险记第二篇

题目描述

自01背包问世之后,小A对此深感兴趣。一天,小A去远游,却发现他的背包不同于01背包,他的物品大致可分为k组,每组中的物品相互冲突,现在,他想知道最大的利用价值是多少。

输入格式

两个数m,n,表示一共有n件物品,总重量为m

接下来n行,每行3个数ai,bi,ci,表示物品的重量,利用价值,所属组数

输出格式

一个数,最大的利用价值

输入输出样例

输入 

45 3
10 10 1
10 5 1
50 400 2

输出 

10

说明/提示

1<=m<=1000 1<=n<=1000 组数t<=100

你可能感兴趣的:(算法篇,动态规划)