[UVa1213]Sum of Different Primes(递推,01背包)

题目链接:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=3654

题意:把n拆成k个不同素数的和,有多少种拆法。

dp(i,j)表示数字为i时,有j个不同素数和的组合数。

先枚举素数的上界k,注意是不同素数,那就再在k个素数中做01背包,dp(i,j)+=dp(i-p,j-1)统计出现次数就行了。

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3
 4 typedef long long LL;
 5 const int maxn = 1320;
 6 bool isprime[maxn];
 7 int prime[maxn];
 8 int pcnt;
 9 int n, k;
10 LL dp[maxn][maxn];
11
12 void init() {
13   memset(isprime, true, sizeof(isprime));
14   memset(prime, 0, sizeof(prime));
15   pcnt = 0;
16 }
17 void getPrime() {
18     init();
19   prime[0] = prime[1] = 0;
20   for(int i = 2; i <= maxn; i++) {
21     if(isprime[i]) prime[++pcnt] = i;
22     for(int j = 1; j <= pcnt; j++) {
23           if(i * prime[j] > maxn) break;
24         isprime[i*prime[j]] = 0;
25         if(i % prime[j] == 0) break;
26     }
27   }
28 }
29
30 int main() {
31     // freopen("in", "r", stdin);
32     // freopen("out", "w", stdout);
33     getPrime();
34     memset(dp, 0, sizeof(dp));
35     dp[0][0] = 1;
36     for(int k = 0; k < pcnt; k++) {
37         for(int i = 1120; i >= 0; i--) {
38             int bound = lower_bound(prime, prime+k, i) - prime + 1;
39             for(int j = 1; j < bound; j++) {
40                 int& p = prime[k];
41                 if(p > i) break;
42                 dp[i][j] += dp[i-p][j-1];
43             }
44         }
45     }
46     while(~scanf("%d%d",&n,&k) && n+k) {
47         printf("%lld\n", dp[n][k]);
48     }
49     return 0;
50 }
时间: 2024-10-18 12:25:12

[UVa1213]Sum of Different Primes(递推,01背包)的相关文章

uva 766 - Sum of powers(数学+递推)

题目连接:uva 766 - Sum of powers 题目大意:将Sk(n)=∑i=1nik化简成Sk(n)=ak+1nk+1+aknk+?+a0M 解题思路: 已知幂k,并且有(n+1)k=C(kk)nk+C(k?1k)nk?1+?+C(0k)n0结论. 所以令 (n+1)k+1?nk+1=C(kk+1)nk+C(k?1k+1)nk?1+?+C(0k+1)n0 nk+1?(n?1)k+1=C(kk+1)(n?1)k+C(k?1k+1)(n?1)k?1+?+C(0k+1)(n?1)0 - 2

UVA1213 Sum of Different Primes(素数打表+dp)

UVA - 1213 Sum of Different Primes Time Limit: 3000MS   Memory Limit: Unknown   64bit IO Format: %lld & %llu Submit Status Description A positive integer may be expressed as a sum of different prime numbers (primes), in one way or another. Given two

UVa1213 - Sum of Different Primes(素数表+DP)

题意是选择k个质数使其和为n,先搞一个素数表然后dp,dp[i][j]表示选了j个数和位i的方案数. #include<bits/stdc++.h> using namespace std; typedef long long ll; const int maxn = 1120; bool check[maxn]; int prime[1120]; ll dp[1122][15]; int init(int n){ memset(check,0,sizeof(check)); int tot=

转化一下就是01背包 CodeForces 433A - Kitahara Haruki&#39;s Gift

Kitahara Haruki has bought n apples for Touma Kazusa and Ogiso Setsuna. Now he wants to divide all the apples between the friends. Each apple weights 100 grams or 200 grams. Of course Kitahara Haruki doesn't want to offend any of his friend. Therefor

Wikioi 1025 01背包变形

这题多加了菜品必选编号,所以刚开始不知道怎么写,原来就把必选的处理下就行了,因为有重复,但是相同的价值与价格都一样,所以这里就直接挑出来就行了. 把不是必选的在里面用dp即可,dp之前也要把重复的舍去. 因为总价格容量为浮点数,所以先乘以10变成整数就可以用01背包了. #include <iostream> #include <cstdio> #include <algorithm> #include <cmath> #include <deque&

416-分割等和子集(01背包)

416-分割等和子集(01背包) 给定一个只包含正整数的非空数组.是否可以将这个数组分割成两个子集,使得两个子集的元素和相等. 注意: 每个数组中的元素不会超过 100 数组的大小不会超过 200 示例 1: 输入: [1, 5, 11, 5] 输出: true 解释: 数组可以分割成 [1, 5, 5] 和 [11]. 示例 2: 输入: [1, 2, 3, 5] 输出: false 解释: 数组不能分割成两个元素和相等的子集. 来源:力扣(LeetCode) 链接:https://leetc

hdu 5104 Primes Problem (素数+递推)

Problem Description Given a number n, please count how many tuple(p1, p2, p3) satisfied that p1<=p2<=p3, p1,p2,p3 are primes and p1 + p2 + p3 = n. Input Multiple test cases(less than 100), for each test case, the only line indicates the positive int

NPU 2015年陕西省程序设计竞赛网络预赛(正式赛)F题 和谐的比赛(递推 ||卡特兰数(转化成01字符串))

Description 今天西工大举办了一场比赛总共有m+n人,但是有m人比较懒没带电脑,另外的n个人带了电脑.不幸的是,今天机房的电脑全坏了只能用带的电脑,一台电脑最多两人公用,确保n>=m.但是大家来的时间不同,随机次序来机房,带电脑的人直接准备比赛而没带电脑的人需要向带电脑并还没和别人公用的人求助(当然会答应).但是,如果不存在带电脑并还没和别人公用的人,那他就要等了,等是很让人头疼的,这就不和谐了,当然假如没有这样的情况发生比赛是很和谐的. Input 输入多组数据,每组数据只有一行m(

uva10891 - Game of Sum(递推,极大极小的思想)

题目:uva10891 - Game of Sum(递推) 题目大意:给出N个数,然后有两个小伙伴在玩游戏,每次可以从这一排数字的两侧中选择一侧开始取连续的数,必须取一个,也可以取完.这两个小伙伴都会采用最优的策略来取数,问第一个小伙伴取数的和与第2个小伙伴取数的和的差值. 解题思路:这题刚开始没什么头绪,只要碰到博弈思想的题目就没什么想法.看了别人的题解才明白. 先从简单的情况来讲如果每个小伙伴只能从两侧的一侧取一个数的话, dp[i][j]:小伙伴在第i个数字到第j个数字能取得的最大值: s