SGU 106.Index of super-prime

时间限制:0.25s

空间限制:4M

题目大意:

                在从下标1开始素数表里,下标为素数的素数,称为超级素数(Super-prime),给出一个n(n<=10000),求最少能用几个超级素数的和表示,并以降序输出这些超级素数。

Sample Input

6

Sample Output

2

3 3

 

{=============}

分析:

 

          读入n以后,先将不大于n的Super-prime筛出,然后DP

           

          简单点的直接用完全背包DP,

 

          稍微优化一点,减少一半的循环次数的话

 

          用 F[i]=max(f[i],f[j]+f[i-j]);

         

          其它细节要动手做了才知道。

 

参考代码:

#include <iostream>
#include <cstring>
using namespace std;
int prime[11000], pd[11000], tol, sPrime[1000], sum;
int f[11000][3], n;
void init() {
	for (int i = 2; i <= n; i++) {
		if (!pd[i]) {
			prime[++tol] = i;
			for (int j = i + i; j <= n; j += i)   pd[j] = 1;
		}
	}
	for (int i = 2; i <= tol; i++)
		if (!pd[i]) sPrime[++sum] = prime[i];
	memset (pd, 0, sizeof pd);
	for (int i = 1; i <= sum; i++)
		pd[sPrime[i]] = 1;
}
void write (int x) {
	if (f[x][0] == 1) cout << x << ' ';
	else
		write (f[x][2]), write (f[x][1]);
}
int main() {
	cin >> n;
	init();
	for (int i = 3; i <= n; i++) {
		if (pd[i]) f[i][0] = 1;
		else {
                for (int j = 3; j <= i / 2 + 1; j++){
                    if (f[j][0] && f[i - j][0] &&
                       (f[i][0] == 0 || f[i][0] > f[j][0] + f[i - j][0])){
                       f[i][0] = f[j][0] + f[i - j][0];
                       f[i][1] = j, f[i][2] = i - j;
                    }
		}
		}
	}
	cout << f[n][0] << endl;
	if (f[n][0])  write (n);
	return 0;
}

 

 

http://www.cnblogs.com/keam37/ keam所有 转载请注明出处

posted @ 2014-06-30 19:28  keambar  阅读(163)  评论(0编辑  收藏  举报