擺花(2012Noip普及組第3題)

擺花ios

(flower.cpp/c/pas) 編程

【問題描述】ide

    小明的花店新開張,爲了吸引顧客,他想在花店的門口擺上一排花,共 m 盆。經過調查顧客的喜愛,小明列出了顧客最喜歡的 n 種花,從 1 到 n 標號。爲了在門口展出更多種花,規定第 i 種花不能超過 ai盆,擺花時同一種花放在一塊兒,且不一樣種類的花需按標號的從小到大的順序依次擺列。spa

    試編程計算,一共有多少種不一樣的擺花方案。code

 

【輸入】blog

輸入文件 flower.in,共 2 行。ci

第一行包含兩個正整數 n 和 m,中間用一個空格隔開。string

第二行有 n 個整數,每兩個整數之間用一個空格隔開,依次表示 a1、a2、……anio

 

【輸出】event

輸出文件名爲 flower.out。

輸出只有一行,一個整數,表示有多少種方案。注意:由於方案數可能不少,請輸出方案數對 1000007 取模的結果。

 

【輸入輸出樣例 1】

flower.in

2 4

3 2

flower.out

2

分析:

動態規劃:

題目要求花必須按從小到大的順序擺放,而且同種類的花必須挨着放,則題目就簡單多了

a[i]表示第i種花最多使用的盆數
f[i][j]表示前i種花,擺j盆的擺放方案數。對於第i種花能夠使用0、一、2...a[i]盆,對應的前i-1種花擺放的盆數爲j-0、j-一、j-二、...j-a[i]
即f[i][j]=f[i-1][j]+f[i-1][j-1]+f[i-1][j-2]+...+f[i-1][j-a[i]] =f[i-1][j-k](0<=k<=a[i],j>=k)
方程寫出來後,最關鍵的就是賦初始值

初始值f[1][0]=1,f[1][1]=1,...f[1][a[1]]=1;
初始值f[i][0]=1;(1<=i<=n)

2 4
3 2
 爲例:
很顯然f[1][1]=f[1][2]=f[1][3]=1;
f[2][1]=2,前2種花,放一盆,則有1,2兩種方法。又
f[2][1]=f[1][0]+f[1][1]=f[1][0]+1能夠推出f[1][0]=1;
一樣的方法能夠推出f[2][0]=f[3][0]=...=f[n][0]=1;
(f[2][2]=f[1][0]+f[1][1]+f[1][2]
f[2][3]=f[1][1]+f[1][2]+f[1][3]
f[2][4]=f[1][2]+f[1][3]+f[1][2])
 
#include<iostream>
#include<cstring>
using namespace std;
int f[200][200]={{0,0}};
int a[200];
int main(){
 int n,m;
 cin>>n>>m;
 for(int i=1;i<=n;i++) cin>>a[i];
 memset(f,0,sizeof(f));
 for(int i=0;i<=a[1];i++) f[1][i]=1;
 for(int i=1;i<=n;i++)f[i][0]=1;
 for (int i=2;i<=n;i++)
  for(int j=1;j<=m;j++)
   for(int k=0;k<=a[i];k++)
    if (j>=k)f[i][j]=(f[i][j]+f[i-1][j-k])% 1000007;
 cout<<f[n][m]<<endl;
 return 0; 
}
View Code

 

 方法2:初始值f[0][0]=1;前0種花擺放0盆的方案數爲1

//題目要求花必須按從小到大的順序擺放,而且同種類的花必須挨着放,則題目就簡單多了 
//f[i][j]表示前i種花,擺j盆的擺放方案數。對於第i種花能夠使用0、一、2...a[i]盆,對應的前i-1種花擺放的盆數爲j-0、j-一、j-二、...j-a[i] 
//即f[i][j]=f[i-1][j]+f[i-1][j-1]+f[i-1][j-2]+...+f[i-1][j-a[i]] (j>a[i])
//初始值f[0][0]=1;前0種花擺放0盆的方案數爲1 
//方程寫出來後,最關鍵的就是賦初始值 
#include<iostream>
#include<cstring>
using namespace std;
int f[200][200]={{0,0}};
int a[200];
int main(){
    int n,m;
    cin>>n>>m;
    for(int i=1;i<=n;i++) cin>>a[i];
    memset(f,0,sizeof(f));
    f[0][0]=1;
//    for(int i=0;i<=a[1];i++) f[1][i]=1;
//    for(int i=1;i<=n;i++)f[i][0]=1;
    for (int i=1;i<=n;i++)
        for(int j=0;j<=m;j++)
            for(int k=0;k<=a[i];k++)
                if (j>=k)f[i][j]=(f[i][j]+f[i-1][j-k])% 1000007;
    cout<<f[n][m]<<endl;
    return 0;    
}
View Code
相關文章
相關標籤/搜索