HDU 3943 数位DP
来源:互联网 发布:家政网络平台 编辑:程序博客网 时间:2024/05/19 00:47
#include <cstdlib>#include <cctype>#include <cstring>#include <cstdio>#include <cmath>#include <algorithm>#include <vector>#include <string>#include <iostream>#include <sstream>#include <map>#include <set>#include <queue>#include <stack>#include <fstream>#include <numeric>#include <iomanip>#include <bitset>#include <list>#include <stdexcept>#include <functional>#include <utility>#include <ctime>#include <cassert>#include <complex>using namespace std;typedef long long ll;typedef long double ld;const int int_max = 0x07777777;const int int_min = 0x80000000;const int inf=0x20202020;const ll mod=1000000007;const double eps=1e-9;const double pi=3.1415926535897932384626;const int DX[]={1,0,-1,0},DY[]={0,1,0,-1};ll powmod(ll a,ll b) {ll res=1;a%=mod;for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;}ll powmod(ll a,ll b,ll mod) {ll res=1;a%=mod;for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;}ll dp[30][21][21];ll p,q,x,y,a[30];ll getcount (int len){ ll sum = 0; int xx=0, yy=0; for(int i = len; i >= 1; i--){ for(int j = 0; j <a[i]; j++){ if(j==4){ if(xx<x) sum += dp[i-1][x-xx-1][y-yy]; continue; } if(j==7) { if(yy<y) sum += dp[i-1][x-xx][y-yy-1]; continue; } sum += dp[i-1][x-xx][y-yy]; } if(a[i]==4) xx++; if(a[i]==7) yy++; if(xx>x || yy>y) break; } return sum;}ll solve (ll x){ for(int i = 0; i < 30; i++) a[i] = 0; int len = 0; while(x){ a[++len] = x%10; x /= 10; } ll ret = getcount(len); return ret;}bool check (ll num){ int xx = 0, yy = 0; while(num){ int t = num%10; if(t==4) xx++; if(t==7) yy++; num /= 10; } if(xx==x && yy==y) return true; return false;}long long Solve(long long k){ int len=1; while(1){ if(dp[len-1][x][y]<k && dp[len][x][y]>=k) //找到目标数的长度 break; len++; } long long res=0; int cx=x,cy=y; for(int i=len;i>0;i--) //从高位开始从小枚举 for(int j=0;j<10;j++){ int tx=cx,ty=cy; if(j==4){ tx--; if(tx<0) continue; } if(j==7){ ty--; if(ty<0) continue; } if(dp[i-1][tx][ty]>=k){ res=res*10+j; cx=tx; cy=ty; break; } k-=dp[i-1][tx][ty]; } return res;}int main(){ for(int i = 0; i < 30; i++){ for(int j = 0; j < 21; j++){ for(int k = 0; k < 21; k++) dp[i][j][k] = 0; } } dp[0][0][0] = 1; for(int i = 1; i < 30; i++){ for(int j = 0; j < 21; j++){ for(int k = 0; k <21; k++){ dp[i][j][k] += dp[i-1][j][k]*8; if(j>0) dp[i][j][k] += dp[i-1][j-1][k]; if(k>0) dp[i][j][k] += dp[i-1][j][k-1]; } } } int T; scanf("%d", &T); int cntt = 1; while(T--){ printf("Case #%d:\n",cntt++); scanf("%I64d%I64d%I64d%I64d",&p,&q,&x,&y); int n; scanf("%d", &n); ll first = solve(p+1); ll second = solve(q+1); for(int i = 0; i < n; i++){ ll k; scanf("%I64d",&k); int len=1; if(first+k > second) { printf("Nya!\n"); continue; } k = first+k; while(1){ if(dp[len-1][x][y]<k && dp[len][x][y]>=k) //找到目标数的长度 break; len++; } long long res=0; int cx=x,cy=y; for(int i=len;i>0;i--) //从高位开始从小枚举 for(int j=0;j<10;j++){ int tx=cx,ty=cy; if(j==4){ tx--; if(tx<0) continue; } if(j==7){ ty--; if(ty<0) continue; } if(dp[i-1][tx][ty]>=k){ res=res*10+j; cx=tx; cy=ty; break; } k-=dp[i-1][tx][ty]; } printf("%I64d\n", res); } }}
0 0
- HDU 3943 数位DP
- hdu 3943 数位dp+二分
- HDU 3943 (二分+数位DP)
- HDU 3943 二分+数位dp
- hdu 3943 经典数位dp好题
- hdu 3555 数位dp
- hdu 3555 数位dp
- HDU 3652 数位DP
- HDU 3555 数位DP
- HDU 3555 \数位DP
- HDU 2089 数位DP
- hdu 3555 数位DP
- hdu 3709 数位DP
- hdu 4352 数位DP
- HDU 3886 数位DP
- HDU 3555 数位DP
- hdu 3555 数位DP
- hdu 3652 数位DP
- SPI总线驱动分析
- 并查集小结
- 内核符号表和kallsyms
- 两种自定义系统弹出键盘上方的view
- 怎样成为一个软件架构师续
- HDU 3943 数位DP
- 各位acmer 学累的时候不妨来看看
- cocos2d-html5 和 cocos2d-jsb的区别
- Android LayoutInflater原理分析,带你一步步深入了解View
- kallsyms的分析
- 华东理工某ACMer总结
- 点击HeadView 实现对cell动态下拉一个TableView,实现对SectionHeader悬停进行设置
- CSVReader 处理CSV文件(.NET)
- ReportStudio入门教程(八十二) - 计算项的运算顺序(续一):交叉表比率