sgu 116 Index of super-prime
题意:用最少的super-prime组成n;
找出所有的super-prime数,只有202个。用完全背包记录能取到n值的最少数量。再找出7要哪些元素。
#include <iostream> #include <cstdio> #include <cmath> #include <algorithm> #include <vector> #include <iomanip> #include <cstring> #include <map> #include <queue> #include <set> #include <cassert> using namespace std; const double EPS=1e-8; const int SZ=10030,INF=0x7FFFFFFF; typedef long long lon; bool p[SZ]; int sz,pri[SZ],spr[SZ],ssz; set<int> st; int dp[220][SZ]; void init() { memset(p,1,sizeof(p)); for(int i=2;i<SZ;++i) { if(p[i]) { for(int j=i*i;j<SZ;j+=i)p[j]=0; pri[++sz]=i; st.insert(i); } } for(int i=1;i<=sz;++i) { if(st.find(i)!=st.end())spr[++ssz]=pri[i]; } } void show(int r,int c) { for(int i=1;i<=r;++i) { for(int j=1;j<=c;++j) { cout<<dp[i][j]<<" "; }cout<<endl; } } void work(int x) { memset(dp,-1,sizeof(dp)); int pos=0; dp[0][0]=0; for(int i=1;i<=ssz;++i) { if(spr[i]<=x)pos=i; else break; for(int j=0;j<=x;++j) { dp[i][j]=dp[i-1][j]; if(j>=spr[i]&&dp[i][j-spr[i]]!=-1) { //if(i==1)cout<<j<<" "<<dp[i][j-spr[i]]<<endl; if(dp[i-1][j]==-1)dp[i][j]=dp[i][j-spr[i]]+1; else dp[i][j]=min(dp[i][j],dp[i][j-spr[i]]+1); } } } //show(pos,x); //if(x!=6)for(;;); if(dp[pos][x]==-1) {//if(x!=6)for(;;); cout<<"0"<<endl; return; } //if(x!=6)for(;;); vector<int> res; for(int i=pos,j=x;i>=1&&j>0;) { if(j>=spr[i]&&dp[i][j-spr[i]]+1==dp[i][j]) { res.push_back(spr[i]); j-=spr[i]; } else --i; } { cout<<dp[pos][x]<<endl; for(int i=0;i<res.size();++i) { if(i)cout<<' '; cout<<res[i]; } } } int main() { std::ios::sync_with_stdio(0); //freopen("d:\\1.txt","r",stdin); init(); //cout<<ssz<<endl; int n; cin>>n; work(n); return 0; }