hdu 4734 F(x) (数位DP中dp数组的重用)
来源:互联网 发布:nginx https转发http 编辑:程序博客网 时间:2024/06/05 19:01
F(x)
Time Limit : 1000/500ms (Java/Other) Memory Limit : 32768/32768K (Java/Other)
Total Submission(s) : 18 Accepted Submission(s) : 9
Problem Description
For a decimal number x with n digits (AnAn-1An-2 ... A2A1), we define its weight as F(x) = An * 2n-1 + An-1 * 2n-2 + ... + A2 * 2 + A1 * 1. Now you are given two numbers A and B, please calculate how many numbers are there between 0 and B, inclusive, whose weight is no more than F(A).
Input
The first line has a number T (T <= 10000) , indicating the number of test cases. For each test case, there are two numbers A and B (0 <= A,B < 10[sup]9[/sup])
Output
For every case,you should output "Case #t: " at first, without quotes. The [I]t[/I] is the case number starting from 1. Then output the answer.
Sample Input
30 1001 105 100
Sample Output
Case #1: 1Case #2: 2Case #3: 13
Source
2013 ACM/ICPC Asia Regional Chengdu Online
题意:
一个A,问你在[0,B]中有多少数,使得F(x)<=F(A) A=(AnAn-1An-2 ... A2A1), F(x) = An * 2n-1 + An-1 * 2n-2 + ... + A2 * 2 + A1 * 1
解析:
这道题数据倒是挺小的,主要是卡时间0.5s,对于每一次输入都memset一遍DP,一定会超时。
所以这道题就要重用dp数组,只需要在所有数据输入前初始化一次就够了。
那么这就要使dp与每一次输入的F(A)无关,这样就要使dp的第二个状态记录,在pos位时,距离边界还剩多少,其实就是F(A)-state,state为pos位之前所有数字的权值和。
那么我的state,就是记录对于目标还剩多少
#include<cstdio>#include<cstring>#include<algorithm>using namespace std;typedef long long int ll;int a[13];ll dp[10][5000];ll FA;ll two[10];ll dfs(int pos,ll state,bool limit,bool lead){ ll ans=0; if(pos==-1) { if(state>=0) return 1; else return 0; } if(state<0) return 0; if(!limit/*&&!lead*/&&dp[pos][state]!=-1) return dp[pos][state]; int up=limit?a[pos]:9; for(int i=0;i<=up;i++) { if(state-i*two[pos]>=0) ans+=dfs(pos-1,state-i*two[pos],limit&&i==up,lead&&i==0); } if(!limit/*&&!lead*/) dp[pos][state]=ans; return ans;}ll solve(ll n){ ll ans=0; int pos=0; while(n) { a[pos++]=n%10; n=n/10; } //memset(dp,-1,sizeof(dp)); ans+=dfs(pos-1,FA,true,true); return ans;}int main(){ int t; ll A,B; scanf("%d",&t); two[0]=1; for(int i=1;i<10;i++) { two[i]=two[i-1]*2; } int k=0; memset(dp,-1,sizeof(dp)); while(t--) { k++; scanf("%lld%lld",&A,&B); FA=0; int j=0; while(A) { int tmp=A%10; FA+=tmp*two[j]; j++; A=A/10; } if(FA>=5000) //因为当B为999999999时,权值最大为4608,不加也没事,不影响时间 printf("Case #%d: %lld\n",k,B+1); else printf("Case #%d: %lld\n",k,solve(B)); }}
阅读全文
0 0
- hdu 4734 F(x) (数位DP中dp数组的重用)
- [HDU 4734]F(x)[数位DP]
- hdu 4734 F(x)(数位DP)
- 简单数位dp-hdu-4734-F(x)
- 【数位DP】 HDU 4734 F(x)
- hdu-4734-F(x)--数位dp
- hdu 4734 F(x) --- 数位dp
- hdu 4734 F(x) (数位dp)
- [数位dp] hdu 4734 F(x)
- hdu 4734 F(x)(数位dp)
- 【HDU】4734 F(x) 数位DP
- HDU 4734 F(x)(数位DP)
- HDU 4734 F(x) (数位DP)
- hdu 4734 F(x) 数位dp
- 【数位DP】 HDU 4734 F(x)
- HDU 4734 F(x)(数位DP)
- HDU 4734 F(X) 数位DP
- Hdu 4734 F(x) (数位dp)
- 牛客练习赛6 A 猴子吃香蕉(等差数列)
- Linux修改文件(目录)权限
- 易生信九天的转录组分析培训班总结
- Qt学习笔记: 实现截图效果
- A
- hdu 4734 F(x) (数位DP中dp数组的重用)
- matlab repmat函数
- select下拉框添加搜索功能
- final、finally、finalize的区别
- YTU OJ 3135: 动态规划基础题目之最长上升子序列(Java解题)
- 神经网络
- JDBC访问数据库的典型操作步骤
- 现代IM系统中消息推送和存储架构的实现
- 亚马逊无人店将对外开放 拜客出行接盘小蓝单车