1. 程式人生 > >hdu2189——512汶川大地震遇難同胞——來生一起走

hdu2189——512汶川大地震遇難同胞——來生一起走

媽媽 
你別哭 
淚光照亮不了 
我們的路 
讓我們自己 
慢慢的走 

媽媽 
我會記住你和爸爸的模樣 
記住我們的約定 
來生一起走 

 

上面這首詩節選自一位詩人紀念遇難同胞的作品,並沒有華麗的語言,但是每位讀者都應該能感受到作品傳達的濃濃愛意,也許還有絲絲無奈。確實,太多的關於孩子不幸的報道衝擊著我們每一顆柔弱的心。正如溫家寶總理所說“多難興邦”,這場災難讓我們很多80後的年輕人一下子成熟了起來,其中很多人以自願者的身份走上了抗震救災的第一線。 
今天,災區又來了n位志願者,抗震救災指揮部需要將他們分為若干個小組,小組的數量不限,但是要求每個小組的人數必須為素數,請問我們有幾種分組的方法呢? 

特別說明: 
1、可以只有一個組; 
2、分組的方法只和人數有關,而與具體的人員無關,即:你可以假設人是無區別的。 

Input

輸入資料首先包含一個正整數C,表示有C組測試用例,然後是C行資料,每行包含一個正整數n(2<=n<=150),表示志願者的總人數。

Output

對於每組測試資料,請輸出分組的方案數目,每個輸出佔一行。

Sample Input

3
3
4
5

Sample Output

1
1
2

題意是讓我們把志願者分組,多少組,每組人數不限,但是每組人數必須式素數;

如果對於一個n直接看他能分成多少組有點困難;

逆向思考,用一些素數去組合,每個素數的個數是不限的,最終希望這些素數組合出的和是等於n的;

現在這個問題和硬幣問題就是同一個模型了;給你幾種硬幣,求出能組成哪些金額;這裡的素數就最小的那些硬幣;

所以直接母函式解題

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e5+7;
int n;
int p[maxn];
int v[maxn];
int t[maxn];
bool prime(int x)
{
    for(int i=2;i*i<=x;++i)
        if(x%i==0) return false;
    return true;
}
int main()
{
    int fuck;
    cin>>fuck;
    int tot=1;
    for(int i=2;i<=160;++i)
        if(prime(i)) p[tot++]=i;///找出150以內的素數
    while(fuck--)
    {
        memset(t,0,sizeof t);
        memset(v,0,sizeof v);
        scanf("%d",&n);
        for(int i=0;i<=n;i+=p[1])
            v[i]=1;
        for(int i=2;p[i]<=n;++i)
        {
            for(int j=0;j<=n;++j)
                for(int k=0;k+j<=n;k+=p[i])
                t[j+k]+=v[j];
            for(int j=0;j<=n;++j)
            {
                v[j]=t[j];
                t[j]=0;
            }
        }
        printf("%d\n",v[n]);

    }
    return 0;
}