1. 程式人生 > >B-icebound的商店-2018年第二屆河北省大學生程序設計競賽

B-icebound的商店-2018年第二屆河北省大學生程序設計競賽

題解 ems 競賽 一個 () 河北 space names int

icebound在得到神殿的寶藏之後,開了一家神秘的商店。你來到了商店,發現慷慨的icebound搞了
TT
T次促銷活動。在每次促銷活動中,icebound都會想出一個他喜歡的數字,如果你買的商品的總價剛好等於icebound喜歡的數字,那麽你就可以免費得到這些商品。
icebound的商店裏一共有
1515
15 件商品,商品的價格和這家商店一樣神秘,第一件商品的價格是
11
1 元,第二件商品的價格是
22
2 元,設第
nn
n件商品的價格為
wnw_n
w
n
?

元,則:
wn=wn?1+wn?2(3≤n≤15)w_n = w_{n-1} + w_{n-2} (3 \leq n \leq 15)

w
n
?

=w
n?1
?

+w
n?2
?

(3≤n≤15)。
如果在某次活動中icebound喜歡的數字是
44
4,那麽共有
44
4 種購買方案:

  1. 買 4個 第一種商品
  2. 買 2個 第一種商品 和 1個 第二種商品
  3. 買 2個 第二種商品
  4. 買 1個 第一種商品 和 1個 第三種商品
    請你算出共有多少種方案可以免費購物,方案數對
    10000000091000000009
    1000000009(
    =109+9=10^9+9
    =10
    9
    +9)取模。

題意:從15個斐波那契數列中找任意個數,使得這些數的和為x.求這樣的方案數.

題解:打牌(DP),dp[j]表示喜歡數j的方案數.I為第I個斐波那契數列的數.狀態轉移方程: dp[j]=(dp[j]+d[j-a[i]])%mod;

#include <bits/stdc++.h>
using namespace std;
const int N=20;
const int M=3e3+5;
const int mod=1e9+9;
int a[N];
int dp[M];
int main(){
    a[0]=1;a[1]=1;
    for(int i=2;i<=15;i++){
        a[i]=a[i-1]+a[i-2];
    }
    int t;
    cin>>t;
    while(t--){
        memset(dp,0,sizeof(dp));
        int n;
        cin>>n;
        dp[0]=1;
        //從15個數內找任意個數(n>=1),使得這n個數的和剛好為x,求這個方案數.
        //dp,將第i個數存入時的方案數,dp[j]=dp[j]+d[j-a[i]];
         
        for(int i=1;i<=15;i++){
            for(int j=a[i];j<=n;j++){
                dp[j]=(dp[j]+dp[j-a[i]])%mod;
            }
        }
        cout<<dp[n]<<endl;
    }
    return 0;
}

B-icebound的商店-2018年第二屆河北省大學生程序設計競賽