分析:赛场上也知道是裸的数位dp,但是无奈刷数位dp题刷的太少了,并不能写出来

一点感想:赛后补题,看了题解的map记录状态,一脸蒙逼,也是非常的不爽,然后想看别人写的,不是递归就是写的比较乱

而且我只刷过最入门的数位dp,例如不要62之类,伤不起啊

然后无奈之下,开了仿照别人题解开了dp[20][10][10][10][10]的数组(别人一般还写个上下限之类的代码,并不能看懂)

这样的数组就可以处理k等于5的情况了,数组第一维代表最高位,后四维代表从当前开始的4个数分别是多少

然后就可以dp[i][...]=dp[i-1][...],当然要符合条件

然后我就是开始仿照“不要62"的那种裸数位dp的方式写这道题,各种统计啊,各种判断矛盾啊,最后辛苦AC

代码比较丑,因为写的比较直接,对于那种只会基础数位dp的人可能有帮助吧,好在最后效率还不错93ms(比某些递归还是快的)

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<iostream>
using namespace std;
typedef long long LL;
const int N=1e3+;
const int INF=0x3f3f3f3f;
const int mod = 1e9+;
const LL ten=;
LL dp[][][][][],sum[][],L,R;
int k;
void up(int cur,int a,int b,int c,int d)
{
if(cur<=)
{
dp[cur][a][b][c][d]=;
sum[cur][a]+=dp[cur][a][b][c][d];
return;
}
for(int i=; i<; ++i)
{
if(i==d||(k>=&&i==c)||(k>=&&i==b)||(k>=&&i==a))continue;
dp[cur][a][b][c][d]+=dp[cur-][b][c][d][i];
}
sum[cur][a]+=dp[cur][a][b][c][d];
}
int bit[],cnt;
LL solve()
{
LL ret=;
for(int i=; i<cnt; ++i)
for(int j=; j<=; ++j)ret+=sum[i][j];
for(int i=cnt; i; --i)
{
int j=(i==cnt)?:;
for(; j<bit[i]; ++j)
{
int a=j;
bool f=false;
for(int p=min(i+k-,cnt); p>i; --p)if(a==bit[p])
{
f=true;
break;
}
if(f)continue;
if(i==)
{
ret+=dp[][a][][][];
continue;
}
for(int b=; b<; ++b)
{
if(b==a)continue;
if(k>=&&i+<=cnt&&b==bit[i+])continue;
if(k>=&&i+<=cnt&&b==bit[i+])continue;
if(k==&&i+<=cnt&&b==bit[i+])continue;
if(i==)
{
ret+=dp[][a][b][][];
continue;
}
for(int c=; c<; ++c)
{
if(c==b)continue;
if(k>=&&c==a)continue;
if(k>=&&i+<=cnt&&c==bit[i+])continue;
if(k==&&i+<=cnt&&c==bit[i+])continue;
if(i==)
{
ret+=dp[][a][b][c][];
continue;
}
for(int d=; d<; ++d)
{
if(!dp[i][a][b][c][d])continue;
if(k==&&i+<=cnt&&d==bit[i+])continue;
ret+=dp[i][a][b][c][d];
}
}
}
}
bool flag=false;
for(int p=min(i+k-,cnt); p>i; --p)if(bit[p]==bit[i])
{
flag=true;
break;
}
if(flag)break;
}
return ret;
}
int main()
{
while(~scanf("%I64d%I64d%d",&L,&R,&k))
{
memset(dp,,sizeof(dp));
memset(sum,,sizeof(sum));
++R;
cnt=;
while(R)bit[++cnt]=R%ten,R/=ten;
for(int i=; i<=cnt; ++i)
{
for(int a=; a<; ++a)
{
if(i==)
{
up(,a,,,);
continue;
}
for(int b=; b<; ++b)
{
if(b==a)continue;
if(i==)
{
up(,a,b,,);
continue;
}
for(int c=; c<; ++c)
{
if(c==b||(k>=&&c==a))continue;
if(i==)
{
up(,a,b,c,);
continue;
}
for(int d=; d<; ++d)
{
if(d==c||(k>=&&d==b)||(k>=&&d==a))continue;
up(i,a,b,c,d);
}
}
}
}
}
LL tmp=solve();
cnt=;
while(L)bit[++cnt]=L%ten,L/=ten;
printf("%I64d\n",tmp-solve());
}
return ;
}

HDU5787 K-wolf Number 数位dp的更多相关文章

  1. 多校5 HDU5787 K-wolf Number 数位DP

    // 多校5 HDU5787 K-wolf Number 数位DP // dp[pos][a][b][c][d][f] 当前在pos,前四个数分别是a b c d // f 用作标记,当现在枚举的数小 ...

  2. codeforces Hill Number 数位dp

    http://www.codeforces.com/gym/100827/attachments Hill Number Time Limits:  5000 MS   Memory Limits: ...

  3. HDU 5787 K-wolf Number 数位DP

    K-wolf Number Problem Description   Alice thinks an integer x is a K-wolf number, if every K adjacen ...

  4. HDU 3709 Balanced Number (数位DP)

    Balanced Number Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others) ...

  5. beautiful number 数位DP codeforces 55D

    题目链接: http://codeforces.com/problemset/problem/55/D 数位DP 题目描述: 一个数能被它每位上的数字整除(0除外),那么它就是beautiful nu ...

  6. hdu 5898 odd-even number 数位DP

    传送门:hdu 5898 odd-even number 思路:数位DP,套着数位DP的模板搞一发就可以了不过要注意前导0的处理,dp[pos][pre][status][ze] pos:当前处理的位 ...

  7. Fzu2109 Mountain Number 数位dp

    Accept: 189    Submit: 461Time Limit: 1000 mSec    Memory Limit : 32768 KB  Problem Description One ...

  8. hdu_3565_Bi-peak Number(数位DP)

    题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=3565 题意:给你一个区间,让你找这个区间内有两个山峰的数的最大和,什么是两个山峰,比如121121   ...

  9. HDU 5179 beautiful number 数位dp

    题目链接: hdu: http://acm.hdu.edu.cn/showproblem.php?pid=5179 bc(中文): http://bestcoder.hdu.edu.cn/contes ...

随机推荐

  1. HDU 4143 A Simple Problem(枚举)

    题目链接 题意 : 就是给你一个数n,让你输出能够满足y^2 = n +x^2这个等式的最小的x值. 思路 : 这个题大一的时候做过,但是不会,后来学长给讲了,然后昨天比赛的时候二师兄看了之后就敲了, ...

  2. 查杀linux线程指令

      工作中重启环境时常常出现内存溢出等等问题,往往需要查杀进程来帮助重启成功,下面就查杀线程的详细指令做下总结:   1.查找需要kill掉的线程: ps -elf|grep [线程关键信息] 比如: ...

  3. http://www.cnblogs.com/huangcong/archive/2010/06/14/1757957.html

    http://www.cnblogs.com/huangcong/archive/2010/06/14/1757957.html http://www.cnblogs.com/langtianya/a ...

  4. [YY题]HDOJ5288 OO’s Sequence

    题意:求这个式子 $\sum \limits_{i=1}^{n} \sum \limits_{j=1}^{m} f(i, j) mod (10^9 + 7)$ 的值 就是对每个区间[i, j]枚举区间 ...

  5. Java运行系统命令并获取值(Process java.lang.Runtime.exec(String[] cmdarray, String[] envp, File dir)

    package test; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; ...

  6. 李洪强iOS开发之OC语言description方法和sel

    OC语言description方法和sel 一.description方法 Description方法包括类方法和对象方法.(NSObject类所包含) (一)基本知识 -description(对象 ...

  7. lintcode 中等题:Letter Combinations of a Phone Number 电话号码的字母组合

    题目 电话号码的字母组合 给一个数字字符串,每个数字代表一个字母,请返回其所有可能的字母组合. 下图的手机按键图,就表示了每个数字可以代表的字母. 样例 给定 "23" 返回 [& ...

  8. AC题目简解-数论

    反素数: HDU2521定义对于任何正整数x,其约数的个数记做g(x).例如g(1)=1,g(6)=4.如果某个正整数x满足:对于任意i(0<i<x),都有g(i)<g(x),则称x ...

  9. Android关于实现EditText中加多行下划线的的一种方法

    1. 重写EditText public class LinedEditText extends EditText { private Paint linePaint; private float m ...

  10. 学习webView控件使用

    WebView 对象用于网页显示使用,简单的学习并使用了一下. 1.首先在 layout 中摆一个全屏的 webview 控件 (main.xml ) <?xml version="1 ...