题意:将n表示成super-prime最少个数和,输出个数,并打印路径按非递增序。
#include <cstdio> #include <algorithm> #include <vector> using namespace std; const int maxn = 2000006; bool vis[maxn]; int tp[150000], p[14004]; int tot, sum; void init() { vis[1] = 1; int i, j; for(i = 2; i*i < maxn; i++) for(j = i*i; j < maxn; j += i) vis[j] = 1; tot = 1; for(i = 2; i < maxn; i++) if(!vis[i]) tp[tot++] = i; for(i = 0; i < tot; i++) if(!vis[i]) p[sum++] = tp[i]; } vector <int> v; bool cmp(int a, int b) { return a > b; } int n, m; int dp[10004], pre[10004]; int main() { init(); int i, j; scanf("%d", &m); n = lower_bound(p, p+sum, m)-p; for(i = 0; i <= m; i++) dp[i] = 100005; dp[0] = 0; for(i = n; i >= 0; i--) for(j = p[i]; j <= m; j++) if(dp[j] > dp[j-p[i]]+1) { dp[j] = dp[j-p[i]] + 1; pre[j] = j-p[i]; } if(dp[m] == 100005) { puts("0"); return 0;} printf("%d\n", dp[m]); for(i = m; i; i = pre[i]) { int t = i - pre[i]; if(t) v.push_back(t); else break; } sort(v.begin(), v.end(), cmp); for(i = 0; i < v.size(); i++) printf("%d ", v[i]); puts(""); return 0; }