牛客假日团队赛5 F随机数 BZOJ 1662: [Usaco2006 Nov]Round Numbers 圆环数 (dfs记忆化搜索的数位DP)...
鏈接:https://ac.nowcoder.com/acm/contest/984/F
來源:牛客網
隨機數
時間限制:C/C++ 1秒,其他語言2秒
空間限制:C/C++ 32768K,其他語言65536K
64bit IO Format: %lld
題目描述
正如你所知,奶牛們沒有手指以至于不能玩“石頭剪刀布”來任意地決定例如誰先擠奶的順序。她們甚至也不能通過仍硬幣的方式。
所以她們通過"round number"競賽的方式。第一頭牛選取一個整數,小于20億。第二頭牛也這樣選取一個整數。如果這兩個數都是 "round numbers",那么第一頭牛獲勝,否則第二頭牛獲勝。
如果一個正整數N的二進制表示中,0的個數大于或等于1的個數,那么N就被稱為"round number" 。例如,整數9,二進制表示是1001,1001 有兩個'0'和兩個'1'; 因此,9是一個round number。26 的二進制表示是 11010 ; 由于它有2個'0'和3個'1',所以它不是round number。
很明顯,奶牛們會花費很大精力去轉換進制,從而確定誰是勝者。 Bessie 想要作弊,而且認為只要她能夠知道在一個指定區間范圍內的"round numbers"個數。
幫助她寫一個程序,能夠告訴她在一個閉區間中有多少Hround numbers。區間是[start, finish],包含這兩個數。 (1 <= Start < Finish <= 2,000,000,000)
輸入描述:
Line 1: 兩個用空格分開的整數,分別表示Start 和 Finish。
輸出描述:
Line 1: Start..Finish范圍內round numbers的個數
示例1
輸入
復制
2 12
輸出
復制
6
說明
2 10 1x0 + 1x1 ROUND
3 11 0x0 + 2x1 NOT round
4 100 2x0 + 1x1 ROUND
5 101 1x0 + 2x1 NOT round
6 110 1x0 + 2x1 NOT round
7 111 0x0 + 3x1 NOT round
8 1000 3x0 + 1x1 ROUND
9 1001 2x0 + 2x1 ROUND
10 1010 2x0 + 2x1 ROUND
11 1011 1x0 + 3x1 NOT round
12 1100 2x0 + 2x1 ROUND
題意:
思路:
數位dp經典題,代碼中有備注,看代碼吧。
細節見代碼:
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #include <queue> #include <stack> #include <map> #include <set> #include <vector> #include <iomanip> #define ALL(x) (x).begin(), (x).end() #define rt return #define dll(x) scanf("%I64d",&x) #define xll(x) printf("%I64d\n",x) #define sz(a) int(a.size()) #define all(a) a.begin(), a.end() #define rep(i,x,n) for(int i=x;i<n;i++) #define repd(i,x,n) for(int i=x;i<=n;i++) #define pii pair<int,int> #define pll pair<long long ,long long> #define gbtb ios::sync_with_stdio(false),cin.tie(0),cout.tie(0) #define MS0(X) memset((X), 0, sizeof((X))) #define MSC0(X) memset((X), '\0', sizeof((X))) #define pb push_back #define mp make_pair #define fi first #define se second #define eps 1e-6 #define gg(x) getInt(&x) #define chu(x) cout<<"["<<#x<<" "<<(x)<<"]"<<endl using namespace std; typedef long long ll; ll gcd(ll a,ll b){return b?gcd(b,a%b):a;} ll lcm(ll a,ll b){return a/gcd(a,b)*b;} ll powmod(ll a,ll b,ll MOD){ll ans=1;while(b){if(b%2)ans=ans*a%MOD;a=a*a%MOD;b/=2;}return ans;} inline void getInt(int* p); const int maxn=1000010; const int inf=0x3f3f3f3f; /*** TEMPLATE CODE * * STARTS HERE ***/int dp[50][50][50]; int cnt; int c[60]; // 前導0狀態: id位之前沒有一個位置是填1的。 int dfs(int id,int cnt1,int cnt0,int limit,int qd0state) {if(!id)// 如果到最后一位{if(qd0state)// 還為前導0狀態,也就是這個數為0,符合條件的。return 1;elsereturn cnt0>=cnt1; 返回是否符合條件}if(!limit&&!qd0state&&dp[id][cnt1][cnt0]!=-1)return dp[id][cnt1][cnt0];// 記憶化搜索部分。int up;// 當前位的上限制。if(limit)// 有限制就本分的用當前位的數值。{up=c[id];}else{up=1;// 無限制,即之前有一位原數是1,但定為了0,后面隨便取都不會比x大、}int res=0;for(int j=0;j<=up;++j){if(qd0state){if(j==0){res+=dfs(id-1,0,0,limit&&(j==up),1);// 繼續前導0.}else{res+=dfs(id-1,cnt1+1,cnt0,limit&&(j==up),0);}}else{if(j==0){res+=dfs(id-1,cnt1,cnt0+1,limit&&(j==up),0);}else{res+=dfs(id-1,cnt1+1,cnt0,limit&&(j==up),0);}}}if(!limit&&!qd0state)dp[id][cnt1][cnt0]=res;// 存信息,當下次無限制,非前導0狀態下,直接返回結果。節省時間return res; } int solve(int x) {cnt=0;while(x)// 處理x的二進制信息。{if(x&1)c[++cnt]=1;elsec[++cnt]=0;x>>=1;}return dfs(cnt,0,0,1,1); }int main() {//freopen("D:\\common_text\\code_stream\\in.txt","r",stdin);//freopen("D:\\common_text\code_stream\\out.txt","w",stdout);int l,r;cin>>l>>r;memset(dp,-1,sizeof(dp));cout<<solve(r)-solve(l-1)<<endl;return 0; }inline void getInt(int* p) {char ch;do {ch = getchar();} while (ch == ' ' || ch == '\n');if (ch == '-') {*p = -(getchar() - '0');while ((ch = getchar()) >= '0' && ch <= '9') {*p = *p * 10 - ch + '0';}}else {*p = ch - '0';while ((ch = getchar()) >= '0' && ch <= '9') {*p = *p * 10 + ch - '0';}} }轉載于:https://www.cnblogs.com/qieqiemin/p/11177573.html
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的牛客假日团队赛5 F随机数 BZOJ 1662: [Usaco2006 Nov]Round Numbers 圆环数 (dfs记忆化搜索的数位DP)...的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: tensorflow 笔记 16:tf.
- 下一篇: 略微讲一下今天的所学吧