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; }
相关文章推荐
- acdream 1064
- hdu 2089 不要62 数位dp
- 关于矩阵优化的DP总结
- HDU 2089不要62 数位dp
- nbut 1545 New Year 2014 数位dp
- BZOJ3029 花神的数论题
- 数位DP
- HDU 2089 不要62
- 数位DP/数位统计 初探
- BZOJ1833: [ZJOI2010]count 数字计数
- 动态规划10_数位DP2
- 动态规划10_数位DP1
- 例题9-22 越大越好 UVa12105
- 例题2.5 数字和与倍数 UVa11361
- 【打CF,学算法——三星级】Codeforces 9C Hexadecimal's Numbers (解法汇总)
- 动态规划晋级——HDU 3555 Bomb【数位DP详解】
- URAL 1057 数位DP
- hdu 2451 Simple Addition Expression(数位dp)
- 数位dp 入门 nbut 1475
- UVA 1640(数位统计)