動態規劃----揹包

一、01揹包

題目:有 N 件物品和一個容量爲 V 的揹包。第 i 件物品的費用是 w[i],價值是 p[i]。求解將哪些物品裝入揹包可使這些物品的費用總和不超過揹包容量,且價值總和最大。  

  例,有3個物品,揹包容量爲10,如下:

 二維解法:

#include<bits/stdc++.h>
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<w[i]) f[i][v]=f[i-1][v];
	   else f[i][v]=max(f[i-1][v],f[i-1][v-w[i]]+p[i]);	    
   }  
   for(i=1;i<=n;i++)   
   {  for(v=1;v<=V;v++) 
	    cout<<setw(5)<<f[i][v]; 
	  cout<<endl;
   }    
}

 初始時:我們初始化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<bits/stdc++.h>
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<<setw(5)<<f[v]; 
	 //cout<<endl; 
   }     
   	cout<<f[V]; 	
}

練習:

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<n<=50。

對於50%的數據,0<n<=1000。

對於100%的數據,0<n<=10000,所有讀入的數均屬於[0,10000],最後結果<=c。

 

 

二、完全揹包

【問題描述】設有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<bits/stdc++.h>
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<<setw(5)<<f[m]; 
	// cout<<endl; 
   }     
   cout<<f[M]; 	
}

第一次循環:

重量 價值 物品 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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章