首页 > 代码库 > CSU 1425 Prime Summation
CSU 1425 Prime Summation
原题链接:http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1425
DP题。
f[i][j]表示当前数字为i,分解式中最大质数为j的方案数,那么,状态转移方程为:
f[i][j] = sum(f[i-j][k])
其中,k为小于等于j的所有质数。
求具体分解式时可以先转化为从小到大(如样例的“顺数第2”可以表述为“倒数第3”),更容易递推编程。
#include <stdio.h> #include <string.h> #define N 205 int n, k; int f[N][N]; int prime[N], cnt; bool isprime[N]; void get_prime() { cnt = 0; memset(isprime, 0, sizeof isprime); for(int i = 2; i < N; i++) { if(!isprime[i]) { prime[cnt++] = i; for(int j = i*2; j < N; j += i) isprime[j] = true; } } } int main() { get_prime(); while(scanf("%d%d", &n, &k) != EOF) { memset(f, 0, sizeof f); f[0][0] = 1; for(int i = 2; i <= n; i++) { for(int j = 0; j < cnt; j++) { if(prime[j] > i) break; for(int t = 0; t <= prime[j]; t++) f[i][prime[j]] += f[i-prime[j]][t]; } } int sum = 0; for(int i = 0; i <= n; i++) sum += f[n][i]; if(k > sum) k = sum; printf("%d\n%d=", sum, n); k = sum - k; bool flag = false; do { int cnt = 0; int i; for(i = 2; i <= n; i++) { if(cnt + f[n][i] > k) break; cnt += f[n][i]; } n -= i; k = k - cnt; if(flag) printf("+"); flag = true; printf("%d", i); } while(n != 0); printf("\n"); } return 0; }
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。