數位DP練習
阿新 • • 發佈:2017-07-08
ble section 0ms stack 存在 mem pac 內存 更新
水題
發布時間: 2017年6月22日 19:15 最後更新: 2017年6月23日 20:10 時間限制: 1000ms 內存限制: 128M
給一個數n,求0~n內有多少個數滿足其二進制形式不存在相鄰的1
比如 0,1,2是可以的,3不可以。
多組輸入,每組輸入一個數。
輸出答案,
復制0
1
數位DP
代碼1:
1 #include<stdio.h> 2 #include<iostream> 3 #include<algorithm> 4 #include<string.h> 5#include<math.h> 6 #include<stdlib.h> 7 #include<ctype.h> 8 #include<stack> 9 #include<queue> 10 #include<map> 11 #include<set> 12 #include<vector> 13 #define ll long long 14 #define db double 15 using namespace std; 16 const int N=1e6+5; 17 constint mod=1e9+7; 18 int n; 19 ll dp[64][2][2]; 20 int a[100]; 21 ll dfs(int p,int pre,int st,int lim){//統計存在相鄰1的數字 22 if(p==-1) return st==1; 23 if(!lim&&dp[p][pre][st]!=-1) return dp[p][pre][st]; 24 ll ans=0; 25 int up=lim?a[p]:1; 26 for(int i=0;i<=up;i++){ 27 int nst=st;28 if(i&&pre) nst=1; 29 ans+=dfs(p-1,i,nst,lim&&i==a[p]); 30 } 31 if(!lim) dp[p][pre][st]=ans; 32 return ans; 33 } 34 void f(int n){ 35 int k=n; 36 memset(dp,-1, sizeof(dp)); 37 memset(a,0, sizeof(a)); 38 int cnt=0; 39 while(n){ 40 a[cnt++]=n%2; 41 n/=2; 42 } 43 printf("%lld\n",k+1-dfs(cnt-1,0,0,1)); 44 } 45 int main(){ 46 while(scanf("%d",&n)==1){ 47 f(n); 48 } 49 }
標程:
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int N = 1e5+5; 4 typedef long long ll; 5 6 ll dp[N][2]; 7 int a[N]; 8 9 ll dfs(int p,int pre,bool lim)//統計不存在相鄰1的數字個數 10 { 11 if(pos == -1) return 1; 12 if(!lim && dp[p][pre] != -1) 13 return dp[p][pre]; 14 int up = lim ? a[p] : 1; 15 ll ans = 0; 16 for(int i =0;i<=up;i++) 17 { 18 if(pre&& i) continue; 19 ans += dfs(p-1,i,lim&&i==a[p]); 20 } 21 if(!lim) dp[p][pre] = ans; 22 return ans; 23 } 24 ll solve(ll n) 25 { 26 memset(dp,-1,sizeof(dp)); 27 memset(a,0,sizeof(a)); 28 int cnt = 0; 29 while(n) 30 { 31 a[cnt++] = n % 2; 32 n /= 2; 33 } 34 return dfs(cnt-1,0,1); 35 } 36 int main() 37 { 38 ll n; 39 while(cin >> n) 40 { 41 cout << solve(n) << endl; 42 } 43 }
數位DP練習