SGU 116. Index of super-prime(完全揹包+輸出路徑)

Let P1, P2, … ,PN, … be a sequence of prime numbers. Super-prime number is such a prime number that its current number in prime numbers sequence is a prime number too. For example, 3 is a super-prime number, but 7 is not. Index of super-prime for number is 0 iff it is impossible to present it as a sum of few (maybe one) super-prime numbers, and if such presentation exists, index is equal to minimal number of items in such presentation. Your task is to find index of super-prime for given numbers and find optimal presentation as a sum of super-primes.

Input

There is a positive integer number in input. Number is not more than 10000.

Output

Write index I for given number as the first number in line. Write I super-primes numbers that are items in optimal presentation for given number. Write these numbers in order of non-increasing.

Sample Input

6

Sample Output

2
3 3

超級質數:一個質數在質數序列裏的下標也是質數,那麼這個數稱爲超級質數。

給定一個數n,問你這個數是不是若干個超級質數的和。

如果是,輸出最小能由多少個超級質數構成,並輸出這些超級質數(這些超級質數可以重複)

如果不是,輸出0。


我們可以先預處理出來所有的超級質數,然後再跑一遍完全揹包,並記錄一下路徑,就可以了。


#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define LL long long
using namespace std;

const int inf = 1e8;
const int maxn = 10010;

int p[maxn],f[maxn];
int cnt = 0;

void init()
{
    LL i,j;
    f[1] = 1;
    for(i=2;i<maxn;i++)
    {
        if(f[i])
            continue;
        p[++cnt] = i;
        for(j=i*i;j<maxn;j+=i)
        {
            f[j] = 1;
        }
    }
    int tcnt = 0;
    for(i=1;i<=cnt;i++)
    {
        if(f[i] == 0)
            p[++tcnt] = p[i];
    }
    cnt = tcnt;
}


int dp[maxn],pre[maxn];


void print(int x)
{
    if(x == 0)
    {
        return;
    }
    printf("%d",x-pre[x]);
    if(pre[x] == 0)
        printf("\n");
    else
        printf(" ");
    print(pre[x]);
}
int main(void)
{
    init();
    int n,i,j;
    while(scanf("%d",&n)==1)
    {
        for(i=1;i<=n;i++)
            dp[i] = inf;
        memset(pre,0,sizeof(pre));
        dp[0] = 0;
        for(i=1;i<=cnt;i++)
        {
            for(j=p[i];j<=n;j++)
            {
                if(dp[j] > dp[j-p[i]] + 1)
                {
                    dp[j] = dp[j-p[i]] + 1;
                    pre[j] = j - p[i];
                }
            }
        }
        if(dp[n] == inf)
        {
            printf("0\n");
            continue;
        }
        printf("%d\n",dp[n]);
        print(n);
    }

    return 0;
}


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