1026: [SCOI2009]windy数

Time Limit: 1 Sec  Memory Limit: 162 MB
Submit: 9670  Solved: 4445
[Submit][Status][Discuss]

Description

  windy定义了一种windy数。不含前导零且相邻两个数字之差至少为2的正整数被称为windy数。 windy想知道,
在A和B之间,包括A和B,总共有多少个windy数?

Input

  包含两个整数,A B。

Output

  一个整数

Sample Input

【输入样例一】
1 10
【输入样例二】
25 50

Sample Output

【输出样例一】
9
【输出样例二】
20

HINT

 

【数据规模和约定】

100%的数据,满足 1 <= A <= B <= 2000000000 。

 

windy数的大致意思是:像135,6913,13579,这样每两个相邻数字的差≥2

数位dp:

正面直接猜想,保存2000000000状态无疑是不可能的,必须采用更加巧妙的方法。

可以设dp数组为:f[i][j],i表示数字位数,j表示最高位的数字

因此可以得到dp方程:

 

\[f[i][j]=\sum_{k=0}^{k\leq 9} f[i-1][k]\left (\left | k-j \right |\geq 2\right )\]

但这只计算出最高位为j的结果,无法求出范围内的结果,这时可以转换思想,求出1~b的结果减去1~a-1的结果,不就是答案了吗?

设len表示数字位数,T[i]表示第i位的数字

首先,ans加上1~len-1位的情况

然后ans加上最高位数字为1~T[len]-1的情况

接着以此类推,加上次最高位1~T[len-1]-1的情况,加上次次最高位1~T[len-2]-1的情况。。。。。。

 

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstdlib>
 4 #include<cmath>
 5 using namespace std;
 6 
 7 #define LL long long
 8 
 9 int a,b;
10 LL f[20][10];
11 
12 LL solve(int t)
13 {
14     LL ans=0;
15     int len=0,T[20];
16     while(t)
17     {
18         T[++len]=t%10;
19         t/=10;
20     }
21     for(int i=1;i<len;i++)
22         for(int j=1;j<=9;j++)
23             ans+=f[i][j];
24     for(int i=1;i<T[len];i++)
25         ans+=f[len][i];
26     for(int i=len-1;i>=1;i--)
27     {
28         for(int j=0;j<T[i];j++)
29             if(abs(j-T[i+1])>=2)
30                 ans+=f[i][j];
31         if(abs(T[i]-T[i+1])<2) break;
32     }
33     return ans;
34 }
35 
36 int main()
37 {
38     scanf("%d %d",&a,&b);
39     for(int i=0;i<=9;i++) f[1][i]=1;
40     for(int i=2;i<=15;i++)
41         for(int j=0;j<=9;j++)
42             for(int k=0;k<=9;k++)
43                 if(abs(k-j)>=2)
44                     f[i][j]+=f[i-1][k];
45     cout<<solve(b+1)-solve(a)<<endl;
46     return 0;
47 }

 

转载于:https://www.cnblogs.com/InWILL/p/9255960.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
中描述了一个幼儿园里分配糖果的问题,每个小朋友都有自己的要求。问题的输入包括两个整NN和KK,表示幼儿园里的小朋友量和要满足的要求量。接下来的KK行表示小朋友们的要求,每行有三个字,XX,AA,BB。如果X=1,表示第AA个小朋友分到的糖果必须和第BB个小朋友分到的糖果一样多;如果X=2,表示第AA个小朋友分到的糖果必须少于第BB个小朋友分到的糖果;如果X=3,表示第AA个小朋友分到的糖果必须不少于第BB个小朋友分到的糖果;如果X=4,表示第AA个小朋友分到的糖果必须多于第BB个小朋友分到的糖果;如果X=5,表示第AA个小朋友分到的糖果必须不多于第BB个小朋友分到的糖果。这个问题可以被看作是一个差分约束系统的问题。 具体地说,可以使用差分约束系统来解决这个问题。差分约束系统是一种通过给变量之间的关系添加约束来求解最优解的方法。对于这个问题,我们需要根据小朋友们的要求建立约束条件,并通过解决这个约束系统来得出最小的糖果量。 在问题的输入中,X的取值范围为1到5,分别对应不同的关系约束。根据这些约束,我们可以构建一个差分约束图。图中的节点表示小朋友,边表示糖果量的关系。根据不同的X值,我们可以添加相应的边和权重。然后,我们可以使用SPFA算法(Shortest Path Faster Algorithm)来求解这个差分约束系统,找到满足所有约束的最小糖果量。 需要注意的是,在读取输入时需要判断X和Y是否合法,即是否满足X≠Y。如果X=Y,则直接输出-1,因为这种情况下无法满足约束条件。 综上所述,为了满足每个小朋友的要求,并且满足所有的约束条件,我们可以使用差分约束系统和SPFA算法来求解这个问题。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [【差分约束系统】【SCOI2011】糖果 candy](https://blog.csdn.net/jiangzh7/article/details/8872699)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* [P3275 [SCOI2011]糖果(差分约束板子)](https://blog.csdn.net/qq_40619297/article/details/88678605)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值