Vijos P1792 擺花(動態規劃,揹包)

P1792擺花

背景

NOIP2012

描述

小明的花店新開張,爲了吸引顧客,他想在花店的門口擺上一排花,共m盆。通過調查顧客的喜好,小明列出了顧客最喜歡的n種花,從1到n標號。爲了在門口展出更多種花,規定第i種花不能超過ai盆,擺花時同一種花放在一起,且不同種類的花需按標號的從小到大的順序依次擺列。試編程計算,一共有多少種不同的擺花方案。

格式

輸入格式

【輸入】 
輸入文件共2行。第一行包含兩個正整數n和m,中間用一個空格隔開。第二行有n個整數,每兩個整數之間用一個空格隔開,依次表示a1、a2、……an。

輸出格式

【輸出】 
輸出只有一行,一個整數,表示有多少種方案。注意:因爲方案數可能很多,請輸出方案數對1000007取模的結果。

樣例1

樣例輸入1[複製]

2 4
3 2

樣例輸出1[複製]

2

限制

1S

提示

【輸入輸出樣例說明】
有2種擺花的方案,分別是(1,1,1,2),(1,1,2,2)。括號裏的1和2表示兩種花,比如第一個方案是前三個位置擺第一種花,第四個位置擺第二種花。

來源

NOIP2012普及組第三題

思路

1)揹包問題,放或不放,將不同的數量看成是不同的物品,轉變爲01揹包
2)求方案數,就是將狀態轉移方程的max變爲求和
3)數很大,記得每次計算後都要取模,不能只對結果取模
4)每次都取模,所以變量定義爲int也沒問題

代碼

#include <iostream>
#define MOD 1000007
#define N 105
using namespace std;
int n,m,a[N],f[N]={1};
int main()
{
	cin>>n>>m;
	for(int i=1;i<=n;i++)			//n種花 
	{	
	  cin>>a[i];					//輸入第i種花的盆數 
	  for(int j=m;j>=0;j--)			//放j盆花,01揹包,第i種花可以取1盆、2盆……a[i]盆,也可以不取,所以要倒序 
	    for(int k=1;k<=min(j,a[i]);k++)	//第i種花能夠取的分數 
	      f[j]=(f[j]+f[j-k])%MOD;		//求方案數,只要將狀態轉移方程的max變成sum即可,每一次都要取模 
	}
	cout<<f[m]<<endl;
	return 0;
}




發佈了56 篇原創文章 · 獲贊 4 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章