1. 程式人生 > >poj 2229 【完全背包dp】【遞推dp】

poj 2229 【完全背包dp】【遞推dp】

cin microsoft cow pro different 偶數 http family sam

poj 2229

Sumsets
Time Limit: 2000MS Memory Limit: 200000K
Total Submissions: 21281 Accepted: 8281

Description

Farmer John commanded his cows to search for different sets of numbers that sum to a given number. The cows use only numbers that are an integer power of 2. Here are the possible sets of numbers that sum to 7:

1) 1+1+1+1+1+1+1
2) 1+1+1+1+1+2
3) 1+1+1+2+2
4) 1+1+1+4
5) 1+2+2+2
6) 1+2+4

Help FJ count all possible representations for a given integer N (1 <= N <= 1,000,000).

Input

A single line with a single integer, N.

Output

The number of ways to represent N as the indicated sum. Due to the potential huge size of this number, print only last 9 digits (in base 10 representation).

Sample Input

7

Sample Output

6

Source

USACO 2005 January Silver 題意:用2的冪次(1,2,4,8...)表示N,有多少種表示方法。
題解: 【完全背包】:   定義:dp[i][j]表示前i個2的冪表示j有多少種方法,則dp[i][j]=Σ{dp[i-1][j-k*c[i]]|0<k*c[i]<=N}   
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 using namespace std;
 6 typedef long long ll;
 7 const int maxn=1e6;
 8 const int mod=1e9;
9 10 int f[maxn]; 11 12 int main() 13 { 14 int N,M; 15 16 while(scanf("%d",&N)==1) 17 { 18 memset(f,0,sizeof(f)),f[0]=1; 19 for(int i=1;; i++) 20 { 21 int t=(1<<(i-1)); 22 if(t>N) break; 23 for(int j=t; j<=N; j++) 24 { 25 f[j]+=f[j-t]; 26 while(f[j]>mod) f[j]-=mod; 27 } 28 } 29 printf("%d\n",f[N]); 30 } 31 return 0; 32 }

【遞推dp】:

  定義:dp[N]表示答案。當N為奇數時,dp[N]=dp[N-1];當N為偶數時,若組成N的數中沒有1,則把這些數除以2,就是dp[N/2];若有1(顯然有1就至少有兩個1),則去掉兩個1,相當於是dp[N-2].所以dp[N]=dp[N/2]+dp[N-2]

  

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 using namespace std;
 6 const int maxn = 1e6;
 7 const int mod = 1e9;
 8 
 9 int dp[maxn];
10 
11 int main()
12 {
13     int n;
14     cin >> n;
15     memset(dp, 0, sizeof(dp));
16     dp[1] = 1, dp[2] = 2, dp[3] = 2, dp[4] = 4;
17     for (int i = 4; i <= n; i++) {
18         if (i % 2 == 1) dp[i] = dp[i - 1]%mod;
19         else dp[i] = (dp[i - 2] + dp[i / 2]) % mod;
20     }
21     cout << dp[n] << endl;
22     return 0;
23 }

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=1e6;
const int mod=1e9;

int dp[maxn+100];

int dfs(int n)
{
    if(dp[n]>0) return dp[n];
    if(n%2==1)
        return dp[n]=dfs(n-1)%mod;
    else
        return dp[n]=(dfs(n-2)+dfs(n/2))%mod;
}

int main()
{
    memset(dp,0,sizeof(dp));
    int n;
    dp[1]=1,dp[2]=2,dp[3]=2,dp[4]=4;
    while(scanf("%d",&n)==1)
    {
        printf("%d\n",dfs(n));
    }
    return 0;
}

poj 2229 【完全背包dp】【遞推dp】