hdu-4734-数位Dp
2016-08-05 16:31
267 查看
按照题意推dp就好
从最高位开始,根据是否受限往下递推记忆化保存结果
从最高位开始,根据是否受限往下递推记忆化保存结果
#include <cstdio> #include <cmath> #include <cstring> #include <string> #include <algorithm> #include <queue> #include <map> #include <set> #include <vector> #include <iostream> using namespace std; typedef int ll; const int maxn=5005+500; int ans=0; int dp[11][maxn]; int aa[11]; // pos = 当前处理的位置(一般从高位到低位) // sum =限制不超过 F(a) // limit = 是否受限,也即当前处理这位能否随便取值。如567,当前处理6这位, // 如果前面取的是4,则当前这位可以取0-9。如果前面取的5,那么当前 // 这位就不能随便取,不然会超出这个数的范围,所以如果前面取5的 // 话此时的limit=1,也就是说当前只可以取0-6。 // int F(int b) { int len=0; while(b) { aa[++len]=b%10; b/=10; } int sum=0; for (int i=len; i>=1; i--) { sum+=(1<<(i-1))*aa[i]; } return sum; } // 用DP数组保存这2个状态是因为往后转移的时候会遇到很多重复的情况。 //可根据需要增加维数,例如pre int dfs(int pos,int sum,int flag) { int ans=0; if (pos==0) //已结搜到尽头,返回"是否找到了答案"这个状态。 { if (sum>=0) return 1; else return 0; } if (sum<0) return 0; //DP里保存的是完整的,也即不受限的答案,所以如果满足的话,可以直接返回。 if (!flag &&dp[pos][sum]!=-1) return dp[pos][sum]; int up; if (flag) up=aa[pos]; else up=9; //根据是否受限确定枚举的上界 for (int i=0; i<=up; i++) { int ff; if (!flag) ff=0; else { if (i==up) ff=1; else ff=0; } ans +=dfs(pos-1,sum-i*(1<<(pos-1)),ff); } //DP里保存完整的、取到尽头的数据 if (!flag) dp[pos][sum]=ans; return ans; } int main() { memset(dp,-1,sizeof dp); int tt,cas=0; scanf("%d",&tt); int m; int cnt=1; while (tt--) { int a,b; scanf("%d%d",&a,&b); int sum =F(a); int len=0; while(b) { aa[++len]=b%10; b/=10; } ans=dfs(len,sum,1); printf("Case #%d: %d\n",cnt++,ans); } }
相关文章推荐
- hdu 4734 F(x)(数位DP)
- hdu 4734 F(x)(数位DP,4级)
- HDU - 4734 F(x) (2013成都网络赛,数位DP)
- HDU 4734 F(x) (数位DP)
- hdu 4734 F(x)(数位dp)
- hdu 4734 F(x) 数位dp
- hdu-4734-F(x)--数位dp
- HDU4734——F(x)(数位DP)
- HDU 4734: F(x) (数位DP)
- HDU_4734 F(x)[数位dp]
- HDU 4734 F(x) ★(数位DP)
- hdu 4734 F(x) (2013成都网络赛G题)(数位DP)
- [HDU 4734]F(x)[数位DP]
- [数位dp] hdu 4734 F(x)
- [HDU 4734]F(x)[数位DP]
- HDU 4734 F(x) (2013成都网络赛,数位DP)
- HDU-4734 数位DP
- HDU-4734 F(x) 数位DP
- 【HDU】4734 F(x) 数位DP
- hdu 4734(数位dp)