码迷,mamicode.com
首页 > Windows程序 > 详细

【luogu2657】【bzoj1026】 [SCOI2009]windy数 [动态规划 数位dp]

时间:2019-05-24 12:51:32      阅读:140      评论:0      收藏:0      [点我收藏+]

标签:++   long   while   数字   str   tar   void   个性   stdin   

P2657 [SCOI2009]windy数

bzoj1026 

一本通说这是一道数位dp模板题 emmmmm 就是逐位确定

f[i][j]表示填了i位数其最高位数字为j 然后就去求可能方案数

分为

  • 不满足x的位数的严格小于x的全部情况
  • 和x的位数相同 但最高位小于x的最高为的全部方案数
  • 和x的位数相同 有一位比x的对应位数小的全部方案数 其余位数对应数字都相同(这是数位dp常用的一个性质:对于一个小于n的数 它从高位到低位一定会出现某一位上的数字小于n所对应这一位上的数字)

PS 因为x不一定为windy数 所以在第三种方案时 我们遇到不满足为windy数时退出

只是我还没搞懂为什么输出dp(b)-dp(a-1)会错一个点

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<queue>
 4 #include<cstring>
 5 #include<cmath>
 6 #include<stack>
 7 #include<algorithm>
 8 using namespace std;
 9 #define ll long long
10 #define rg register
11 const int N=2000000000+5,pw=11,inf=0x3f3f3f3f,P=19650827;
12 int a,b,f[pw+5][pw+5];
13 ll base[pw+5];
14 template <class t>void rd(t &x)
15 {
16     x=0;int w=0;char ch=0;
17     while(!isdigit(ch)) w|=ch==-,ch=getchar();
18     while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
19     x=w?-x:x;
20 }
21 
22 void prepare()
23 {
24     base[0]=1;
25     for(rg int i=1;i<=pw;++i) base[i]=base[i-1]*10;
26     for(rg int i=0;i<10;++i) f[1][i]=1;//
27     for(rg int i=2;i<=pw;++i)
28     for(rg int j=0;j<10;++j)
29     for(rg int k=0;k<10;++k)
30     if(abs(j-k)>=2) f[i][j]+=f[i-1][k]; 
31 }
32 
33 int dp(int x)
34 {
35     int p,ans=0;
36     for(p=0;p<=pw;++p) if(base[p]>x) break;
37     if(!p) return ans; 
38     for(rg int i=1;i<p;++i)
39     for(rg int j=1;j<10;++j)
40     ans+=f[i][j];//不满p位的
41     int pre=x/base[p-1];x%=base[p-1];
42     for(rg int i=1;i<pre;++i)
43     ans+=f[p][i];//满足p位 但第p位数字小于x的
44     for(rg int i=p-1;i>0;--i)
45     {
46         int cur=x/base[i-1];
47         for(rg int j=0;j<cur;++j)
48         if(abs(pre-j)>=2) ans+=f[i][j];
49         if(abs(pre-cur)<2) break; 
50         pre=cur,x%=base[i-1];
51      } 
52      return ans;
53 }
54 
55 int main()
56 {
57     //freopen("in.txt","r",stdin);
58     //freopen("nocows.out","w",stdout);
59     prepare();
60     rd(a),rd(b);
61     printf("%d",dp(b+1)-dp(a));
62     return 0;
63 }

 

【luogu2657】【bzoj1026】 [SCOI2009]windy数 [动态规划 数位dp]

标签:++   long   while   数字   str   tar   void   个性   stdin   

原文地址:https://www.cnblogs.com/lxyyyy/p/10917314.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!