现在的位置: 首页 > 综合 > 正文

SGU 116 筛素数+多重背包输出路径

2014年07月19日 ⁄ 综合 ⁄ 共 833字 ⁄ 字号 评论关闭

题意:将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;
}

抱歉!评论已关闭.