您的位置:首页 > 其它

hdu 3943 数位dp+二分

2015-10-24 20:38 323 查看
题意: 求p - q 范围内满足有x个4和y个7的第K个数。


思路: 数位dp。然后二分位置。


code

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int T;
ll p, q;
int query;
int x, y;
int num[10010];
ll dp[100][100][100];
ll dfs(int i, int n4, int n7, bool e, int n1, int n2){
if(i == -1){
if(n4 == n1&&n7 == n2) return 1;
return 0;
}
if(!e&&dp[i][n4][n7] != -1) return dp[i][n4][n7];
int End = e?num[i]:9;
ll res = 0;
for(int k=0; k<=End; k++){
if(k == 4) res += dfs(i-1, n4+1, n7, e&&k==End, n1, n2);
else if(k == 7) res += dfs(i-1, n4, n7+1, e&&k==End, n1, n2);
else res += dfs(i-1, n4, n7, e&&k==End, n1, n2);
}
return e?res:dp[i][n4][n7] = res;
}
ll solve(ll a, int n1, int n2){
int cnt = 0;
while(a){
num[cnt++] = a % 10;
a /= 10;
}
return dfs(cnt-1, 0, 0, true, n1, n2);
}
int main(){
cin>>T;
ll tmp;
int icase = 0;
while(T--){
scanf("%lld %lld %d %d", &p, &q, &x, &y);
memset(dp, -1, sizeof(dp));
cin>>query;
printf("Case #%d:\n", ++icase);
while(query--){
scanf("%lld", &tmp);
ll l = p+1; ll r = q;
ll s = solve(p, x, y);
s += tmp;
ll ans = -1;
while(l<=r){
ll mid = (l + r) >> 1;
ll tt = solve(mid, x, y);
if(tt >= s){
ans = mid;
r = mid - 1;
}
else l = mid + 1;
}
if(ans == -1) puts("Nya!");
else printf("%lld\n", ans);
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  数位dp