HDU3943 K-th Nya Number 数位DP

来源:互联网 发布:字符型二维数组初始化 编辑:程序博客网 时间:2024/05/17 03:52

记录自己的刷题状态...题目是求在[p,q]这个区间内,符合有x个4,y个7这个状态的第k个数字是多少...也就是符合条件的第k小,求完之后用上二分法确定第k小...就是先求出0-p内有多少个符合的,在求出0-mid有多少符合的,如果差刚好是k那么就是它了- -。

#include<stdio.h>#include<string.h>#include<stdlib.h>__int64 dp[21][21][21];int num[21];__int64 dfs(int site,int a,int b,int x,int y,int f){if(site==0){if(a==x&&b==y)return 1;return 0;}if(!f&&dp[site][a][b]!=-1)return dp[site][a][b];__int64 ans=0;int len=f?num[site]:9;for(int i=0;i<=len;i++){if(i==4)ans+=dfs(site-1,a+1,b,x,y,f&&i==len);else if(i==7)ans+=dfs(site-1,a,b+1,x,y,f&&i==len);elseans+=dfs(site-1,a,b,x,y,f&&i==len);}if(!f)dp[site][a][b]=ans;return ans;}__int64 solve(__int64 a,int x,int y){int i=0;while(a){num[++i]=a%10;a=a/10;}return dfs(i,0,0,x,y,1);}int main(){int T;scanf("%d",&T);memset(dp,-1,sizeof(dp));for(int cas=1;cas<=T;cas++){__int64 p,q,s;int x,y,n;scanf("%I64d %I64d %d %d",&p,&q,&x,&y);scanf("%d",&n);printf("Case #%d:\n",cas);while(n--){__int64 k;scanf("%I64d",&k);s=solve(p,x,y);s+=k;__int64 l,r,ans=-1;l=p+1;r=q;while(l<=r){__int64 mid=(l+r)/2;if(solve(mid,x,y)>=s){ans=mid;r=mid-1;}elsel=mid+1;}if(ans==-1)printf("Nya!\n");elseprintf("%I64d\n",ans);}}return 0;}


0 0