有一位售票員給乘客售票。對於每位乘客,他會賣出多張連續的票,直到已賣出的票的編號的數字之和不小於給定的正數k。然後他會按照相同的規則給下一位乘客售票。
—初始時,售票員持有的票的編號是從l到r的連續整數。請你求出,售票員可以售票給多少位乘客。
—資料規模:1 ≤ l ≤ r≤ 1018,1 ≤ k ≤1000。
劉聰論問題,以前做此類題都是按位考慮,可是偏偏此題用樹考慮極為方便(居然不滿足區間減法)。
由於是十進位制,所以劃分成十叉樹,但是由於「數字之和不小於給定的正數k」,所以不一定等於,則對與一棵子樹來說可能前幾個節點會給別人,自己又會搶一些節點,因此多記錄一維前多少的部分與上一組合併,在轉移時將最後一組剩餘多少記錄一下然後類似線段樹找到所需區間進行dp。
一開始我將線段樹似的dfs和dp混在一起,結果狀態給搞錯了,本來想改進結果發現如果dfs與dp在一起則表示的狀態量就很大了,所以乾脆分開弄,反而清晰了不少。
#include #include #include struct tree f[20][200][1000],ans;
const int oo=1073741819;
int g[20][200][1000],s,a[40],b[40],c[40];
long long k,l,r;
tree merge(tree x,tree y)
void dp(int h,int sum,int rem)
f[h][sum][rem].b=rem;
for (i=0;i<=9;i++)
}void dfs(int h,int sum,int lcal,int lcar)
if (lcal) ll=a[h+1];else ll=-oo;
if (lcar) rr=b[h+1];else rr=oo;
for (i=0;i<=9;i++)
if ((ll<=i)&&(i<=rr))
}void init()
for (i=1;i<=s;i++) c[i]=a[i];
for (i=s;i>=1;i--) a[i]=c[s-i+1];
for (i=1;i<=s;i++) c[i]=b[i];
for (i=s;i>=1;i--) b[i]=c[s-i+1];
dfs(0,0,1,1);
printf("%i64d\n",ans.a);
}int main()
SGU 390 Tickets 數字dp,較難
sgu 390 tickets 有一位售票員給乘客售票。對於每位乘客,他會賣出多張連續的票,直到已賣出的票的 編號的數字之和不小於給定的正數 k 然後他會按照相同的規則給下一位乘客售票。初始時,售票員持有的票的編號是從 l到 r 的連續整數。請你求出,售票員可以售票給多少位乘客。資料規模 1 l r...
數字DP 數字統計
題目 給定兩個正整數a和b,求在 a,b 中的所有整數中,每個數碼 digit 各出現了多少次。數字dp 1 分情況,逐位討論。2 模型 計算在 l,r 中有多少個數滿足條件。3 套路 將問題轉化為 1,r 1,l 1 只需回答 1,x 的詢問即可。思路1.算出 1,x 1 按位拆分,為後面做鋪墊 ...
數字統計 區間數字
time limit 1 sec memory limit 128 mb submit 8 solved 3 submit status web board 一本書的頁碼從自然數1 開始順序編碼直到自然數n。書的頁碼按照通常的習慣編排,每個頁碼都不含多餘的前導數字0。例如,第6 頁用數字6 表示,而...