站点一览:

  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. PHP金额工具类之将阿利伯数字转换为大写中文数字

    1.将阿拉伯数字转换为中文大写数字 <?php namespace core\components; class PriceHelper extends \yii\base\Component{ ...

  2. APP测试重点(转载)

      1.安装卸载测试: app在不同的操作系统(安卓和ios),不同的版本,不同的机型上是否都能安装成功: 在安装过程中,突然断网或网络不好,是否给出有好的提示,网络恢复之后是否能正常下载: 在安装过 ...

  3. 在delphi中生成GUID

    什么是 GUID ? 全球唯一标识符 (GUID) 是一个字母数字标识符,用于指示产品的唯一性安装.在许多流行软件应用程序(例如 Web 浏览器和媒体播放器)中,都使用 GUID. GUID 的格式为 ...

  4. Ubuntu16.04网络不能访问解决办法

      问题: 系统重启后,网络不能正常使用,加载网络配置失败,且重启网络时也提示错误. 解决方法: 在定位的过程中发现是配置中的网络设备号与实际设备号不符. 1.查看网络配置中的配备号: vi /etc ...

  5. openblas下载安装编译

    编译好的库: https://github.com/JuliaLinearAlgebra/OpenBLASBuilder/releases 源码编译 下载:https://github.com/xia ...

  6. SQL Server For XML

    FOR XML PATH 有的人可能知道有的人可能不知道,其实它就是将查询结果集以XML形式展现,有了它我们可以简化我们的查询语句实现一些以前可能需要借助函数活存储过程来完成的工作.那么以一个实例为主 ...

  7. 51nod 1503 猪和回文(dp滚存)

    题面 大意:在一个n*m的矩形中从(1,1)走到(n,m)而且走过的路径是一条回文串,统计方案数 sol:我们考虑从(1,1)和(n,m)两端开始算,这样就只要保证每次经过的字符一样就可以满足回文了, ...

  8. Vmware 控制脚本

    #_*_ coding:utf8 _*_ import sys,time import yaml import re import os import ssl import random import ...

  9. SpringMVC 集成Log4j

    项目地址:https://github.com/xiaoqiu-duan/DataProject.git 1.添加jar <dependency> <groupId>org.s ...

  10. django 配置邮件发送 send_email

    导入 send_email 所用方法导入 from django.core.mail import send_mail 因为使用的需要指明 发送人 所以要把 setting.py 中的 EMAIL_F ...