题目大意:
在一个由素数组成的数列 2,3,5,7......
定义超级素数,数列中的第k项为超级素数当且仅当k也为素数
给定n
如果n能被超级素数的和所表示
输出最少要多少个超级素数,以及这些超级素数
否则输出impossible
暴力找出超级素数
然后多重背包
//Lib #include<cstdio> #include<cstring> #include<cstdlib> #include<cmath> #include<ctime> #include<iostream> #include<algorithm> #include<vector> #include<string> #include<queue> using namespace std; //Macro #define rep(i,a,b) for(int i=a,tt=b;i<=tt;++i) #define rrep(i,a,b) for(int i=a,tt=b;i>=tt;--i) #define erep(i,e,x) for(int i=x;i;i=e[i].next) #define irep(i,x) for(__typedef(x.begin()) i=x.begin();i!=x.end();i++) #define read() (strtol(ipos,&ipos,10)) #define sqr(x) ((x)*(x)) #define pb push_back #define PS system("pause"); typedef long long ll; typedef pair<int,int> pii; const int oo=~0U>>1; const double inf=1e20; const double eps=1e-6; string name="",in=".in",out=".out"; //Var int f[10008],g[10008],p[10008],prime[10008],cnt,pos,n; bool isPrime(int n) { if(n<2)return false; rep(i,2,sqrt((double)n)) if(n%i==0)return false; return true; } void Pre() { rep(i,2,n) if(isPrime(i))prime[++cnt]=i; int cnt2=cnt; cnt=0; rep(i,1,cnt2) { if(isPrime(i))p[++cnt]=prime[i]; } } void Work() { scanf("%d",&n); Pre(); rep(i,1,n)f[i]=(oo>>1); rep(i,1,cnt)rep(j,p[i],n) { if(f[j]>f[j-p[i]]+1) { f[j]=f[j-p[i]]+1; g[j]=j-p[i]; } } if(f[n]==(oo>>1)){cout<<0<<endl;return;} cout<<f[n]<<endl; pos=n; rep(i,1,f[n]-1) cout<<pos-g[pos]<<' ',pos=g[pos]; cout<<pos<<endl; } int main() { // freopen((name+in).c_str(),"r",stdin); // freopen((name+out).c_str(),"w",stdout); // Init(); Work(); // PS; return 0; }