题解:洛谷P11557 [ROIR 2016 Day 2] 有趣数字

题目传送门。

考虑数位 dp,也就是记忆化搜索,设置一个搜索函数 \(dfs\),有三个参数,一个是当前位数,表示搜到哪一位了,一个是从第一位到上一个位数是否全部顶上界,从第一位到上一位全部顶上界的意思是从第一位到上一位是否和对应的 \(a\) 的数位上的数相同(\(a\) 指的是搜索的字符串),第三个参数是表示上一个数是多少。

同时我们发现可以记忆化,于是设置一个三维的数组 \(f_{i,j,k}\),搜索完后就记录,如果发现当前这一位是已经搜索过的,那就直接返回答案。

附上搜索代码:

int dfs(int x,int ding,int d)
{
	if(x == a.size())//到了最后一位
	{
		return 1;
	}
	if(f[x][ding][d]!=-1)//已经搜索过
	{
		return f[x][ding][d];//直接返回
	}
	int ans = 0;
	for(int i = d;i<=(ding?a[x]-'0':9);i++)//如果一直顶了上界,这一位也只能到a[x],如果没有一直顶,那就可以到最大的一位数9
	{
		int dingg = ding&&i == a[x]-'0';//计算是否一直顶上界
		ans = (ans+dfs(x+1,dingg,i))%mod;//加和
	}
	return f[x][ding][d] = ans;//记录
}

然后重头戏来了,按照理论,我们应该使用搜索 \(r\) 的结果减去搜索 \(l-1\) 的结果,再 \(\bmod (10^9+7)\),但是 \(l\) 高达 \(10^{100}\),无法使用变量存储,写高精度计算 \(l-1\) 又太麻烦,于是巧妙转化,换成求搜索 \(r\) 的减去搜索 \(l\) 的加上 \(l\) 是否为“有趣数”。转化完之后代码就好写了(主函数):

int main()
{
	int ans = 0;
	string l,r;
	cin >> l >> r;
	a = r;
	memset(f,-1,sizeof(f));//清空
	ans = (ans+dfs(0,1,0))%mod;//加上搜索r的,取模
	a = l;
	memset(f,-1,sizeof(f));
	ans = (ans-dfs(0,1,0)+mod)%mod;//减去搜索l的,取模
	int flag = 1;//算一下l是否为“有趣数”
	for(int i = 0;i<a.size();i++)
	{
		if(a[i-1]>a[i])
		{
			flag = 0;
			break;
		}
	}
	ans = (ans+flag)%mod;//加上,取模
	printf("%d",ans);
    return 0;
}

总代码:

#include<bits/stdc++.h>
using namespace std;
const int mod = 1e9+7;
string a;
int f[105][2][10];
int dfs(int x,int ding,int d)
{
	if(x == a.size())
	{
		return 1;
	}
	if(f[x][ding][d]!=-1)
	{
		return f[x][ding][d];
	}
	int ans = 0;
	for(int i = d;i<=(ding?a[x]-'0':9);i++)
	{
		int dingg = ding&&i == a[x]-'0';
		ans = (ans+dfs(x+1,dingg,i))%mod;
	}
	return f[x][ding][d] = ans;
}
int main()
{
	int ans = 0;
	string l,r;
	cin >> l >> r;
	a = r;
	memset(f,-1,sizeof(f));
	ans = (ans+dfs(0,1,0))%mod;
	a = l;
	memset(f,-1,sizeof(f));
	ans = (ans-dfs(0,1,0)+mod)%mod;
	int flag = 1;
	for(int i = 0;i<a.size();i++)
	{
		if(a[i-1]>a[i])
		{
			flag = 0;
			break;
		}
	}
	ans = (ans+flag)%mod;
	printf("%d",ans);
    return 0;
}
posted @   林晋堃  阅读(11)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示