HDU 2082 找單詞(母函數基礎)

H - 找單詞
Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u

Description

假設有x1個字母A, x2個字母B,..... x26個字母Z,同時假設字母A的價值爲1,字母B的價值爲2,..... 字母Z的價值爲26。那麼,對於給定的字母,可以找到多少價值<=50的單詞呢?單詞的價值就是組成一個單詞的所有字母的價值之和,比如,單詞ACM的價值是1+3+14=18,單詞HDU的價值是8+4+21=33。(組成的單詞與排列順序無關,比如ACM與CMA認爲是同一個單詞)。 
 

Input

輸入首先是一個整數N,代表測試實例的個數。 
然後包括N行數據,每行包括26個<=20的整數x1,x2,.....x26. 
 

Output

對於每個測試實例,請輸出能找到的總價值<=50的單詞數,每個實例的輸出佔一行。
 

Sample Input

2 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 9 2 6 2 10 2 2 5 6 1 0 2 7 0 2 2 7 5 10 6 10 2 10 6 1 9
 

Sample Output

7 379297
 

解題思路:

母函數

這道題開始不會早,搜了別人的代碼,感覺所有過了這道題的代碼幾乎都一模一樣,但是對於多項式*多項式的過程中,係數的處理還是不是很清楚,感覺需要後期的嘗試不斷地 理解和體會,先當做一個多項式*多項式的模板記住把。。


代碼:

#include<iostream>
#include<cstdio>
#include<cstring>

using namespace std;

const int N=50;

int c1[N+10],c2[N+10],num[30];

int main(){

    //freopen("input.txt","r",stdin);

    int t;
    scanf("%d",&t);
    while(t--){
        memset(c1,0,sizeof(c1));    //c1[ ]保存當前得到的多項式各項係數
        memset(c2,0,sizeof(c2));    //c2[ ]保存每次計算時的臨時結果
        for(int i=1;i<=26;i++)
            scanf("%d",&num[i]);
        c1[0]=1;                //相當於用X^0去乘以後面的多項式 
        for(int i=1;i<=26;i++){     //要乘以26個多項式
            for(int j=0;j<=N;j++)   //c1的各項的指數
                for(int k=0;k<=num[i] && j+k*i<=N;k++)  //k*i表示被乘多項式各項的指數,(X^0*i + X^1*i + X^2*i + ……)
                    c2[j+k*i]+=c1[j];       //指數相加得j+k*i,加多少隻取決於c1[j]的係數,因爲被乘多項式的各項係數均爲1
            for(int j=0;j<=N;j++){
                c1[j]=c2[j];
                c2[j]=0;
            }
        }
        int ans=0;
        for(int i=1;i<=N;i++)
            ans+=c1[i];
        printf("%d\n",ans);
    }
    return 0;
}



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