poj 2229 【完全背包dp】【遞推dp】
阿新 • • 發佈:2018-02-21
cin microsoft cow pro different 偶數 http family sam
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).
A single line with a single integer, N.
題解:
【完全背包】:
定義:dp[i][j]表示前i個2的冪表示j有多少種方法,則dp[i][j]=Σ{dp[i-1][j-k*c[i]]|0<k*c[i]<=N}
poj 2229
SumsetsTime 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
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,有多少種表示方法。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】