FAFU 1411 质数之和

来源:互联网 发布:一级office考试软件 编辑:程序博客网 时间:2024/06/04 17:48

题意:任何一个大于1的正整数N都能分解成多个质数之和,并且这种分解式可以有多种。例如N=9就可以有M=4种分解式:9=7+2=5+2+2=3+3+3=3+2+2+2。我们把7+2=2+7看成是同一种分解式,如果分解式中的质数相同次序不同,取质数由大到小排序的那个分解式。给定两个正整数N和K, 求出M,再输出第K大的和式。


思路:背包+贪心吧


/*    author:ray007great    version:1.0*/#include<cstdio>#include<algorithm>#include<iostream>#include<cstring>#include<cstdlib>#include<cmath>#include<vector>#include<set>#include<map>#include<string>#include<time.h>#include<queue>using namespace std;typedef long long ll;//c++#pragma comment(linker, "/STACK:102400000,102400000")// g++//int size = 256 << 20; // 256MB//char *p = (char*)malloc(size) + size;//__asm__("movl %0, %esp\n" :: "r"(p) );#define sf(a) scanf("%d",&a)#define sfs(a) scanf("%s",a)#define sfI(a) scanf("%I64d",&a)#define pf(a) printf("%d\n",a)#define pfI(a) printf("%I64d\n",a)#define rep(i,a,b) for(int i=(a);i<=(b);i++)#define repd(i,a,b) for(int i=(a);i>=(b);i--)#define rep1(i,a,b) for(int i=(a);i<(b);i++)#define clr(a) memset(a,0,sizeof(a))#define clr1(a) memset(a,-1,sizeof(a))#define pfk  printf("fuck\n")/*  define *//* clock  *///clock_t start, finish;//start = clock();//finish = clock();//double duration = (double)(finish - start)/CLOCKS_PER_SEC;//printf( "%.10f seconds\n", duration );/* clock *//* data *//* data */int pr[200];int dp[250][100];vector<int> ans;int n,k;bool isPrime(int x){    if(x==2) return 1;    for(int i=2;i<x;i++){        if(x%i==0) return false;    }    return true;}void dfs( int v, int now ){    if( v == 0) return ;    while( v < pr[ now ] ) now--;    if(now == 0) return ;    if( dp[ v - pr[ now ] ][ now ] >= k ) {        ans.push_back( pr[now] );        dfs( v - pr[now], now );    }    else{        k -= dp[ v - pr[ now ] ][ now ];        dfs( v, now - 1);    }}int main(){    int cnt=0;    for(int i = 2; i <= 200; i++){        if( isPrime(i) ) pr[ ++cnt ]=i;    }    while(cin>>n>>k){        if(n + k == 0) return 0;        clr(dp);        for(int i = 1; i<= cnt; i++) dp[0][i] = 1;        for(int l = 1; l <= cnt; l++){            for(int i = 1; i <= l; i++){                for(int j = pr[i]; j <= n; j++){                    dp[j][l] += dp[j-pr[i]][l];                }            }        }        if(k > dp[ n ][ cnt ]) k = dp[n][ cnt ];        cout<< dp[ n ][ cnt ] <<endl;        int now = cnt;        while( pr[ now ] > n ) now--;        ans.clear();        dfs( n, now );        int sz = ans.size();        cout<< n << "=";        for(int i = 0; i < sz; i++)            if(i) cout<< "+" << ans[i];            else cout<< ans[i];        cout<< endl;    }    return 0;}// 159 1// 200 209


0 0