站点一览:

  1. hdu 2089"不要62"
  2. hdu 4734"F(X)"
  3. poj 3252"Round Numbers"
  4. hdu 3709"Balanced Number"

1.hdu 2089"不要62"

题解:

  题目过于简单,不再赘述。

AC代码:

 #include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define mem(a,b) memset(a,b,sizeof(a)) int a,b;
int digit[];
int dp[][];//dp[i][0]:位置i的前一个位置不为6的总方案数;dp[i][1]正好相反 int DFS(int curPos,int preNum,int isSix,bool limit)
{
if(curPos == -)
return ;
if(!limit && dp[curPos][isSix] != -)
return dp[curPos][isSix]; int up=limit ? digit[curPos]:;
int ans=;
for(int i=;i <= up;++i)
{
if((preNum == && i == ) || i == )
continue;
ans += DFS(curPos-,i,i == ,limit&& i == digit[curPos]);
}
if(!limit)
dp[curPos][isSix]=ans;
return ans;
}
int Solve(int x)
{
int k=;
while(x)
{
digit[k++]=x%;
x /= ;
}
return DFS(k-,,,true);
} int main()
{
while(~scanf("%d%d",&a,&b) && a+b)
{
mem(dp,-);
printf("%d\n",Solve(b)-Solve(a-));
}
return ;
}

2.hdu 4734"F(X)"

Problem Description
For a decimal number x with n digits (AnAn-1An- ... A2A1), we define its weight as F(x) = An * 2n- + An- * 2n- + ... + A2 * + A1 * .
Now you are given two numbers A and B, please calculate how many numbers are there between and B, inclusive, whose weight is no more than F(A). Input
The first line has a number T (T <= ) , indicating the number of test cases.
For each test case, there are two numbers A and B ( <= A,B < ) Output
For every case,you should output "Case #t: " at first, without quotes. The t is the case number starting from . Then output the answer.

题解:

  初始想法:

  定义dp[ i ][ j ] : [ 0,i ] 位置满足 weight == j 的数的总个数;

  求出F(a)后,便利 i : 0~F(a) ,求出 [0,b] weight == i 的数的总个数,作加和;

  很不幸,TLE,不过,还是挺开心的,毕竟是在看题解前按照自己的想法成功敲出的代码,虽然TLE了;

  正解:定义dp[ i ][ j ] : [ 0,i ]位置满足 weight <= j 的数的总个数,然后,每次判断 dp[ i ][ j ]是否可以直接返回;

AC代码:

 #include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define mem(a,b) memset(a,b,sizeof(a)) int a,b;
int power[]={,,,,,,,,};
int digit[];
int dp[][];//dp[i][j]:前i位F值小于等于j的总个数 int F(int x)
{
int sum=;
int base=;
while(x)
{
sum += (x%)*base;
base <<= ;
x /= ;
}
return sum;
}
int DFS(int need,int curPos,int curSum,bool limit)
{
if(curPos == -)
return curSum <= need ? :; if(curSum > need)
return ; if(!limit&&dp[curPos][need-curSum] != -)
return dp[curPos][need-curSum]; int up=limit ? digit[curPos]:;
int ans=;
for(int i=;i <= up;++i)
ans += DFS(need,curPos-,curSum+i*power[curPos],limit&&i==digit[curPos]); if(!limit)
dp[curPos][need-curSum]=ans; return ans;
}
int Solve(int x)
{
int k=;
while(x)
{
digit[k++]=x%;
x /= ;
}
int f=F(a);
return DFS(f,k-,,true);
}
int main()
{
int test;
scanf("%d",&test);
mem(dp,-);
for(int kase=;kase <= test;++kase)
{
scanf("%d%d",&a,&b);
printf("Case #%d: %d\n",kase,Solve(b));
}
return ;
}

3.poj 3252"Round Numbers"

题意:

  输入两个十进制正整数a和b,求闭区间 [a ,b] 内有多少个Round number

  所谓的Round Number就是把一个十进制数转换为一个无符号二进制数,若该二进制数中0的个数大于等于1的个数,则它就是一个Round Number

  注意,转换所得的二进制数,最高位必然是1,最高位的前面不允许有0

题解:

  定义dp[ i ][ j ][ k ] : 在没有限制的情况下,[0,i]位置满足 0 的个数等于 j,1 的个数等于 k 的数的总个数;

  坑点:前导零不能算在 0 的总个数中;

因为poj炸了,所以一直处于wait状态,不过对拍了一下他人的AC代码,正确率是可以保证的,应该也不会超时吧orz;

wait代码:

 #include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define mem(a,b) memset(a,b,sizeof(a)) int a,b;
int digit[];
int dp[][][]; //isSat:只有当出现第一个不为0的位数时才为true
//作用是去掉前导0的影响
int DFS(int curPos,int totZero,int totOne,bool isSat,bool limit)
{
if(curPos == -)
return totZero >= totOne; if(!limit && dp[curPos][totZero][totOne] != -)
return dp[curPos][totZero][totOne]; int up=limit ? digit[curPos]:;
int ans=;
for(int i=;i <= up;++i)
{
bool flag=(isSat || i != );
ans += DFS(curPos-,totZero+(flag&&i==),totOne+(i==),flag,limit&&i==digit[curPos]);
}
if(!limit)
dp[curPos][totZero][totOne]=ans;
return ans;
}
int Solve(int x)
{
int k=;
while(x)
{
digit[k++]=x%;
x >>= ;
}
return DFS(k-,,,false,true);
}
int main()
{
mem(dp,-);
while(~scanf("%d%d",&a,&b))
printf("%d\n",Solve(b)-Solve(a-)); return ;
}

4.hdu 3709"Balanced Number"

题意:

  给一个很大的区间[x,y],(0 ≤ x ≤ y ≤ 1018).问:区间里面的数满足如下规则的有多少个?

  规则:将数字放在天平上,天平能够平衡。天平的轴随意,力臂就是数字下标到天平轴的下标的距离。

题解:

  脑海中浮现出如何记忆化搜索的代码,可就是没想到如何判断当前数是否为"balance number",无奈之下,查阅大佬代码orz;

  坑点:全为0的数会重复计算,需要减去重复的部分

AC代码:

 #include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define ll long long
#define mem(a,b) memset(a,b,sizeof(a)) ll a,b;
int digit[];
ll dp[][][]; //curSum:记录curPivot左边的和+右边的和,只有curSum == 0才能说明
// curPivot左边的和==右边的和
ll DFS(int curPos,int curPivot,int curSum,bool limit)
{
if(curPos == -)
return curSum == ? :;
if(curSum < )
return ;
if(!limit && dp[curPos][curPivot][curSum] != -)
return dp[curPos][curPivot][curSum]; int up=limit ? digit[curPos]:;
ll ans=;
for(int i=;i <= up;++i)
ans += DFS(curPos-,curPivot,curSum+i*(curPos-curPivot),limit&&i==digit[curPos]); if(!limit)
dp[curPos][curPivot][curSum]=ans;
return ans;
}
ll Solve(ll x)
{
if(x == -)
return ;
int k=;
while(x)
{
digit[k++]=x%;
x /= ;
}
ll ans=;
for(int i=k-;i >= ;--i)
ans += DFS(k-,i,,true);
return ans-k+;
//0个0,1个0,.......,(k-1)个0,全为0的情况被记录了k次,须减去(k-1)个重复的
}
int main()
{
int test;
scanf("%d",&test);
mem(dp,-);
while(test--)
{
scanf("%lld%lld",&a,&b);
printf("%lld\n",Solve(b)-Solve(a-));
}
return ;
}

数位DP入门题的更多相关文章

  1. HDU 2089 不要62【数位DP入门题】

    不要62 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submis ...

  2. HDU 2089 - 不要62 - [数位DP][入门题]

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2089 Time Limit: 1000/1000 MS (Java/Others) Memory Li ...

  3. 数位DP入门题——[hdu2089]不要62

    数位DP是我的噩梦. 现在初三了,却没AC过数位DP的题目. 感觉数位DP都是毒瘤-- 题目 hdu不用登录也可以进去,所以就不把题目copy到这里来了. 题目大意 求区间[n,m][n,m][n,m ...

  4. 【数位dp】【HDU 3555】【HDU 2089】数位DP入门题

    [HDU  3555]原题直通车: 代码: // 31MS 900K 909 B G++ #include<iostream> #include<cstdio> #includ ...

  5. hdu 2089 数位dp入门题

    #include<stdio.h> //dp[i][0]代表不存在不吉利数字 //dp[i][1]代表不存在不吉利数字但是以2开头 //dp[i][2]代表存在不吉利数字 #define ...

  6. hdu3555 Bomb (数位dp入门题)

    Bomb Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others)Total Submi ...

  7. xbz分组题B 吉利数字 数位dp入门

    B吉利数字时限:1s [题目描述]算卦大湿biboyouyun最近得出一个神奇的结论,如果一个数字,它的各个数位相加能够被10整除,则称它为吉利数.现在叫你计算某个区间内有多少个吉利数字. [输入]第 ...

  8. 数位dp入门 hdu2089 不要62

    数位dp入门 hdu2089 不要62 题意: 给定一个区间[n,m] (0< n ≤ m<1000000),找出不含4和'62'的数的个数 (ps:开始以为直接暴力可以..貌似可以,但是 ...

  9. poj 3254 状压dp入门题

    1.poj 3254  Corn Fields    状态压缩dp入门题 2.总结:二进制实在巧妙,以前从来没想过可以这样用. 题意:n行m列,1表示肥沃,0表示贫瘠,把牛放在肥沃处,要求所有牛不能相 ...

随机推荐

  1. StringBuilder与String有哪些区别?

    System.String具备不可修改性,在程序中这样的特性容易产生性能上的问题.针对这个问题.NET提供的StringBuilder类可以解决类似的问题. String 和 StringBuilde ...

  2. JQ remove()方法实现似收货地址逐一删除的效果

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  3. centos无网络问题

  4. cefSharp 开发随笔

    最近用cefSharp开发一点简单的东西.记录一点随笔,不定时更新. 1.用nuget安装完之后,架构要选择x86或者x64,否则编译会报错(截止到Chrome 55版本) 2.向Chrome注册C# ...

  5. size_t的使用

    size_t的取值range是目标平台下最大可能的数组尺寸 典型的例子:x64平台下size_t是8位,而x32平台下是4位: int在两个平台下均为4位 所以在使用的时候一定要配置好对应的平台,否则 ...

  6. 【转】微信小程序开发之图片等比例缩放 获取屏幕尺寸图片尺寸 自适应

    原文[https://blog.csdn.net/qq_31383345/article/details/53127804] 早上在论坛上看到有人写了关于图片等比例缩放的文章,只是判断了图片宽是否大于 ...

  7. kubernetes 创建系统用户来支持访问 dashboard

    Dashboard: 1.部署: 下载yaml文件  可以直接运行也可以下载下来kubectl apply -f https://raw.githubusercontent.com/kubernete ...

  8. HDU2710-Max Factor-分解质因子

    给出N个MAXN以内的不同的数,求出素因子最大的数. 使用朴素的方法分解素因子即可.时间复杂度为N*log(MAXN) #include <cstdio> #include <alg ...

  9. BZOJ 1497 最大获利

    最大权闭合子图 对于这个题,可以抽象成一个图论模型,如果我们把用户与其要求建立的中转站连边,获得的利益看成正权值,付出的代价看成负权值,我们可以发现,选取一个用户的时候,就相当于选取了一个闭合子图. ...

  10. GCD HDU - 1695 (欧拉 + 容斥)

    GCD Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submiss ...