您的位置:首页 > 其它

2016弱校联盟十一专场10.5(12点场) Increasing or Decreasing

2016-10-06 22:30 387 查看
题目链接:

https://www.bnuoj.com/bnuoj/contest_show.php?cid=8563#problem/101902

题意:就是要你找x<=a的这个数的不严格递增或递减的个数

例如 112233, 123,而312这种就不算.

个人感想:我的想法很简单,就是用数位dp找到 不严格递增的个数+不严格递减的个数-重复的平衡个数(例如111111)遍是答案了,我不知道为什么这里有个问题在于我加了一个 min的判断数据就少了,不知道是不是数据记忆出错还是怎么的我现在也想不通. 我是拍了一下别人代码的一个数据就知道出错了,我感觉上就是那个min里,我都不知道怎么少了.好吧我来讲讲我的思路:

dp[i][j][k][l]:代表的是:位数,前一个数字是j,是否为前导0得到的数据(1/0),l代表递增递减的类型.

然后套基本的数位dp即可.

问题:求某位大佬来帮我看看代码憋- -我也不知道那个min哪里错了.加上我感觉没什么太大问题(解决)

ps:昨天晚上想了一想我知道哪里错了,我既然把min设置了,就会出现我后面出现了true,那么代表可以默认地计数,那么久有问题了,例如 694587 .如果我枚举到6 9第2位,我会设置成 65,可是本来这个数已经是69了,那么递减根本就不合法了,所以就会加多了,是差值变小了,所以 后面的 e是不能随便乱改的…

分析:数位dp

AC代码:

/* Author:GavinjouElephant
* Title:
* Number:
* main meanning:
*
*
*
*/

#include <iostream>
using namespace std;
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <sstream>
#include <cctype>
#include <vector>
#include <set>
#include <cstdlib>
#include <map>
#include <queue>
//#include<initializer_list>
//#include <windows.h>
//#include <fstream>
//#include <conio.h>
#define MaxN 0x7fffffff
#define MinN -0x7fffffff
#define lson 2*k
#define rson 2*k+1
typedef  long long ll;
const ll INF=0x3f3f3f3f;
const ll maxn=1e5+10;
ll Scan()//读入整数外挂.
{
ll res = 0, ch, flag = 0;

if((ch = getchar()) == '-')             //判断正负
flag = 1;

else if(ch >= '0' && ch <= '9')           //得到完整的数
res = ch - '0';
while((ch = getchar()) >= '0' && ch <= '9' )
res = res * 10 + ch - '0';
return flag ? -res : res;
}
void Out(ll a)    //输出外挂
{
if(a>9)
Out(a/10);
putchar(a%10+'0');
}
ll top;
ll dig[20];
ll dp[25][11][2][2];//i 位数,上一位的数字,前导0,递增递减(1/0)
ll T;
ll l,r;

ll dfs(ll pos,ll pre,ll zero,ll type,bool e)
{
if(pos==0)return (ll)1;

if(!e&&dp[pos][pre][zero][type]!=(ll)-1)
return dp[pos][pre][zero][type];

ll ans=0;
if(type)
{
ll limi=e?dig[pos]:9;

for(ll i=0;i<=limi;i++)
{
if(i<pre)continue;//-->

if(zero&&i==0)
{
ans+=dfs(pos-1,0,1,type,e&&i==limi);
}
else  ans+=dfs(pos-1,i,0,type,e&&i==limi);
}

}
else
{
ll limi=e?dig[pos]:9;

//limi=min(pre,limi);
//到现在也不知道为什么加上上面的那句话就会数据少了..
//如果知道的话帮我看看咯...我是外加了-->if才过的
for(ll i=0;i<=limi;i++)
{
if(i>pre)continue;//-->
if(zero&&i==0)
{
ans+=dfs(pos-1,10,1,type,e&&i==limi);
}
else ans+=dfs(pos-1,i,0,type,e&&i==limi);
}

}

if(!e)
{
dp[pos][pre][zero][type]=ans;
}
return ans;
}

ll solve(ll x)
{
if(x==0) return 1;
top=0;
ll ans=0;
ll now=0;
ll temp=x;
while(x)
{
dig[++top]=x%10;
x/=10;

now=now*10+1;
}

ll de=temp/now+(top-1)*9+1;//平衡的个数

ans+=dfs(top,0,1,1,true);

ans+=dfs(top,10,1,0,true);

return ans-de;

}
int main()
{

scanf("%lld",&T);
memset(dp,-1,sizeof(dp));
//solve((ll)1000000000000000000);
while(T--)
{
scanf("%lld%lld",&l,&r);
printf("%lld\n",solve(r)-solve(l-1));

}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: