首页 > 其他分享 >P2602 [ZJOI2010] 数字计数&HDU 2089 (数位dp)

P2602 [ZJOI2010] 数字计数&HDU 2089 (数位dp)

时间:2023-09-28 09:22:16浏览次数:44  
标签:HDU 2089 15 int ll len ZJOI2010 include 数位

luogu
HDU
最近在复习数位dp
数位dp,就是在一些计数问题的时候按照一位一位的顺序依次计算,通常可以采用记忆化搜索的方式
这两道题就是很典型的数位dp
数位dp通常要记录是不是顶着上限,有没有前导零,到了哪一位以及一些特殊的条件要求。
数位dp通常要把某个区间的问题转变成两个区间的差来方便求解
比如说第一题,这一道题每一个数位填了几对后面数位除了前导零和是否顶着上限以外没有额外的影响,所以我们在求解的时候可以选择
直接在当前位数算出当前位的贡献然后去计算下一位的贡献。

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#include<stack>
#include<set>
#include<map>
#include<ctime>
#include<bitset>
#define ll long long
using namespace std;
ll f[15];
ll now[15];
ll len;
ll ksm[15];
ll p[15];
ll a,b;
ll dfs(int len,int x,bool zero,bool lim){
	if(!len){
		return 0;
	}
	if(!lim&& !zero && (~f[len])) return f[len];
	ll cnt=0;
	int up= lim? p[len] : 9;
	for(int i=0;i<=up;++i){
		if(i==0&&zero) cnt+=dfs(len-1,x,1,lim&&i==up);
		else if (i==x&&lim&&i==up){
			cnt+=1+now[len-1]+dfs(len-1,x,0,1);
		}else if(i==x){
			cnt+=ksm[len-1]+dfs(len-1,x,0,0);
		}else{
			cnt+=dfs(len-1,x,0,lim&&i==up);
		}
	}
	if((!lim)&&(!zero)) f[len]=cnt;
	return cnt;
}
ll ask(ll x,ll tag){
	ll len=0;
	while(x){
		p[++len]=x%10;
		x/=10;
		now[len]=now[len-1]+ksm[len-1]*p[len];
	}
	memset(f,-1,sizeof(f));
	return dfs(len,tag,1,1);
}
int main(){
	scanf("%lld%lld",&a,&b);
	ksm[0]=1;
	for(int i=1;i<=12;++i){
		ksm[i]=ksm[i-1]*10ll;
	}
	for(int i=0;i<=9;++i) printf("%lld ",ask(b,i)-ask(a-1,i));
	return 0;
}

再看HDU这一道题,大体的思路是相似的,但是知道当前位是多少,虽然说后面的答案是固定的,也就是说我们可以记忆化处理,但是
仅仅知道当前位是不可能知道后面的情况的,必须往后搜索才可以。所以说计算贡献的位置有所变化。

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#include<stack>
#include<set>
#include<map>
#include<ctime>
#include<bitset>
#define ll long long
using namespace std;
ll f[15];
ll now[15];
ll len;
ll ksm[15];
ll p[15];
ll a,b;
ll dfs(int len,int x,bool zero,bool lim){
	if(!len){
		return 0;
	}
	if(!lim&& !zero && (~f[len])) return f[len];
	ll cnt=0;
	int up= lim? p[len] : 9;
	for(int i=0;i<=up;++i){
		if(i==0&&zero) cnt+=dfs(len-1,x,1,lim&&i==up);
		else if (i==x&&lim&&i==up){
			cnt+=1+now[len-1]+dfs(len-1,x,0,1);
		}else if(i==x){
			cnt+=ksm[len-1]+dfs(len-1,x,0,0);
		}else{
			cnt+=dfs(len-1,x,0,lim&&i==up);
		}
	}
	if((!lim)&&(!zero)) f[len]=cnt;
	return cnt;
}
ll ask(ll x,ll tag){
	ll len=0;
	while(x){
		p[++len]=x%10;
		x/=10;
		now[len]=now[len-1]+ksm[len-1]*p[len];
	}
	memset(f,-1,sizeof(f));
	return dfs(len,tag,1,1);
}
int main(){
	scanf("%lld%lld",&a,&b);
	ksm[0]=1;
	for(int i=1;i<=12;++i){
		ksm[i]=ksm[i-1]*10ll;
	}
	for(int i=0;i<=9;++i) printf("%lld ",ask(b,i)-ask(a-1,i));
	return 0;
}

标签:HDU,2089,15,int,ll,len,ZJOI2010,include,数位
From: https://www.cnblogs.com/For-Miku/p/17734854.html

相关文章

  • FlashDuty Changelog 2023-09-21 | 自定义字段和开发者中心
    FlashDuty:一站式告警响应平台,前往此地址免费体验!自定义字段FlashDuty已支持接入大部分常见的告警系统,我们将推送内容中的大部分信息放到了Lables进行展示。尽管如此,我们用户还是会有一些扩展或定制性的需求,比如人工标记一个故障是否为误报。因此我们提供了自定义字段功能,......
  • FlashDuty Changelog 2023-09-07 | 新增深色模式与主题配置
    FlashDuty:一站式告警响应平台,前往此地址免费体验!FlashDuty现在已经全面支持了深色模式,这为您提供了更柔和的光线和舒适的界面外观。并且,您可以根据自己的喜好和使用环境动态切换深色和浅色模式与主题,提高使用体验的个性化和灵活性。深色模式效果预览为了确保在深色模式下......
  • FlashDuty Changelog 2023-09-07 | 新增深色模式与主题配置
    FlashDuty:一站式告警响应平台,前往此地址免费体验!FlashDuty现在已经全面支持了深色模式,这为您提供了更柔和的光线和舒适的界面外观。并且,您可以根据自己的喜好和使用环境动态切换深色和浅色模式与主题,提高使用体验的个性化和灵活性。深色模式效果预览为了确保在深色模式下能够呈现......
  • FlashDuty Changelog 2023-09-21 | 自定义字段和开发者中心
    FlashDuty:一站式告警响应平台,前往此地址免费体验!自定义字段FlashDuty已支持接入大部分常见的告警系统,我们将推送内容中的大部分信息放到了Lables进行展示。尽管如此,我们用户还是会有一些扩展或定制性的需求,比如人工标记一个故障是否为误报。因此我们提供了自定义字段功能,来进一......
  • Solution -「HDU」Ridiculous Netizens
    Desc.  给定一棵\(N\)个节点无根树,找出满足以下条件的集合\(S\)的数量:\(S\subseteq\{1,\dots,n\}\);\(S\)的导出子图联通;\(\displaystyle\prod_{v\inS}a_v\leqslantM\)。Sol.  点分治,统计包括当前分治中心的集合数量,如果从子树的角度入手会发现并不好做—......
  • HDU 4609
    题目链接description给定一个长度为\(n\)的序列\(A\),元素值域大小为\(10^5\)。求从中任选三个不同位置的元素,以它们的值为三边能够成三角形的概率。solution设有\(cnt\)种选三个不同的元素构成三角形的方案,则答案显然为\(\dfrac{6cnt}{n(n-1)(n-2)}\)。\(a,b,c(a\leq......
  • [BCB]E2089 Identifier 'ReadPragram' cannot have a type qualifier
    这些天一直在改程序,今天突然冒出来如下错误:[C++Error]Unit1.cpp(4114):E2089Identifier'ReadPragram'cannothaveatypequalifier[C++Error]Unit1.cpp(6751):E2089Identifier'Button1Click'cannothaveatypequalifier[C++Error]Unit1.cpp(8593):E2139D......
  • HDU 1054 Strategic Game 树形DP/二分图匹配
    第一次写博文,想了半天就拿一道dp/graph的题作为处作吧此题有两种常见解法(题意比较简单,就不赘述)1.二分图最大匹配       此题等价于问一棵树中最小点覆盖数。树形结构可以把它看做是一个二分图,一个点集为奇数层,另一个点集为偶数层,显然满足二分图定义,可以套用求二分图最小点......
  • hdu 4712 Hamming Distance-----随机
    计算出二进制数中有多少个1:数据范围太大,想到可以随机如果你在第一次调用rand()之前没有调用srand(),那么系统会为你自动调用srand()。------百度rand#include<cstdio>#include<cstring>#include<algorithm>#include<time.h>usingnamespacestd;constintN=1e5+10......
  • hdu 4705 Y
    dfs1.要#pragmacomment(linker,"/STACK:16777216")2.扩栈要vc++编译环境3.不能用%lld,要用%I64d,无语。。#pragmacomment(linker,"/STACK:16777216")//手动扩栈#include<stdio.h>#include<string.h>#include<stdlib.h>#include<vector>using......