[UVa1213]Sum of Different Primes(递推,01背包)
生活随笔
收集整理的這篇文章主要介紹了
[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 }?
轉載于:https://www.cnblogs.com/kirai/p/6096865.html
總結
以上是生活随笔為你收集整理的[UVa1213]Sum of Different Primes(递推,01背包)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java 消息机制 ActiveMQ入门
- 下一篇: Python 元组 (tuple)