首页 > 其他分享 >数数

数数

时间:2022-10-02 08:55:27浏览次数:29  
标签:11 数数 le int Cuber else dp

题目描述

Cuber QQ 和 Cuber CC 在无聊时喜欢通过写数字来检验他们两的默契程度。

假设 Cuber QQ 写的数是 $X$,Cuber CC 写的数是Y。

当 $X$ 的最高位等于 $Y$ 的个位,且 $Y$ 的最高位等于 $X$ 的个位时,我们称 $(X,Y)$ 是一对“默契数”(这里顺序没有关系,即对于不同的 $X$ 和 $Y$ ,$(X,Y)$ 和 $(Y,X)$ 是不同的)。

现在他们两想知道,对于所有的 $1\le X,Y\le N$ ,有多少对默契数 $(X,Y)$ 呢?

输入格式

一行一个正整数 $N$ 。

输出格式

一行一个整数表示答案。

样例

输入

11

输出

12

解释

合法的 $12$ 对默契数为:$(1,1),(1,11),(2,2),(3,3),(4,4),(5,5),(6,6),(7,7),(8,8),(9,9),(11,1),(11,11)$ 。

数据范围

对于40%的数据,满足 $N\le 10$

对于70%的数据,满足 $N\le 2000$

对于100%的数据,满足 $N\le 200000$

枚举 \(X\),那么我们现在需要知道有多少个数的最高位为 \(X\) 的最低位,最低位为 \(X\) 的最高位。跑个数位 dp 。

#include<bits/stdc++.h>
using namespace std;
const int pw[]={1,10,100,1000,10000,100000};
int n,x,y,dp[6][2][6];
long long ans;
int dfs(int t,int k,int z)
{
	if(!~t)
		return 1;
	if(~dp[t][k][z])
		return dp[t][k][z];
	int p=1,q=9;
	if(t==z)
		p=q=y;
	else if(t>z)
		p=q=0;
	else if(!t)
		p=q=x;
	else
		p=0;
	if(!k)
		q=min(q,n/pw[t]%10); 
//	printf("%d %d %d %d %d\n",t,k,z,p,q);
	int ret=0;
	for(int i=p;i<=q;i++)
		ret+=dfs(t-1,k|(i<n/pw[t]%10),z);
//	printf("%d %d %d %d\n",t,k,z,ret);
	return dp[t][k][z]=ret;
}
int main()
{
	scanf("%d",&n);
	for(int i=1,t;i<=n;i++)
	{
		memset(dp,-1,sizeof(dp));
		t=i;
		while(t)
			x=t%10,t/=10;
		y=i%10;
		if(x==y)
			++ans;
//		printf("%d %d\n",x,y);
		if(x&&y)
			for(int j=1;j<=5;j++)
				ans+=dfs(5,0,j);
//		printf("%lld\n",ans);
	}
	printf("%lld",ans);
}

标签:11,数数,le,int,Cuber,else,dp
From: https://www.cnblogs.com/mekoszc/p/16748239.html

相关文章