站点一览:

  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. ReCAPTCHA & 手势验证

    手势验证 recaptcha https://www.vaptcha.com/ https://www.vaptcha.com/document https://www.iviewui.com/com ...

  2. sql中的begin catch 。。。end catch 的用法

    begin catch ...end  catch 是用来处理异常的 begintry--SQLendtry begincatch--sql (处理出错动作)endcatch 我们将可能会出错的sql ...

  3. 洛谷 P1102 A−B数对

    题目描述 出题是一件痛苦的事情! 题目看多了也有审美疲劳,于是我舍弃了大家所熟悉的 A+BA+BA+B ProblemProblemProblem ,改用 A−BA-BA−B 了哈哈! 好吧,题目是这 ...

  4. 微软已发布 Windows 10 Timeline 功能的官方 Chrome 插件

    微软已发布 Windows 10 Timeline 功能的官方 Chrome 插件,这个插件名为 Web Activities,功能是跨 Windows 10 和 Microsoft Launcher ...

  5. Vue 快速入门

    Vue框架介绍 中文文档: https://cn.vuejs.org/v2/guide/ Vue是一个构建数据驱动的web界面的渐进式框架. 目标是通过尽可能简单的API实现响应式的数据绑定和组合的视 ...

  6. 大学jsp实验5request,response

    1.request对象的使用 (1)编写一个包含有表单的JSP页面form.jsp,其中包含可以输入姓名和出生地的文本框,提交表单后在另一个页面中显示用户提交的姓名和出生地.请写出相应代码: form ...

  7. scrapy爬取知乎问答

    登陆 参考 https://github.com/zkqiang/Zhihu-Login # -*- coding: utf-8 -*- import scrapy import time impor ...

  8. 洛谷P2512 糖果传递

    环形均分纸牌 普通的均分纸牌前缀和的总和就是答案. 但是这里是环形的,要断开的位置需要最佳,我们把每个数减去sum/n,这样总的前缀和就为0了,若在第k个数之后把环断开,环形前缀和可以统一写成s[i] ...

  9. Spring 学习笔记(二)

    spring 核心 (xml方式.注解方式) 两种方式实现 ioc :控制反转 aop : 面向切面

  10. verilog parameter 位宽问题

    前言 一直以为parameter 的位宽是无限的,其实不然. 流程: 仿真一下就知道啦: 用处: 精准控制位宽理论上会占用更少的内存,其他好像并没有什么卵用,注意不要越界,我这里系统默认32bit位宽 ...