**2020暑期牛客多校H.Harmony Pairs(数位DP)

本文介绍了一种使用数位动态规划(数位DP)解决特定类型数学问题的方法。通过实例解析,展示了如何设定状态、转移方程以及记忆化搜索策略,以高效求解数位差相关题目。代码示例清晰地解释了数位DP的实现细节。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目链接:https://ac.nowcoder.com/acm/contest/5671/H
题意:…
解题思路:利用数位DP,
dp[pos][sum][limita][limitb][limit]
pos当前搜索位置 sum当前A与B数位差 limita A是否为上界情况 limitb B是否为上界情况 limit A小于或等于B
因为N最大取十进制100位,所以数位差绝对值最大值小于1000,所以以base=1000为数位差起点,从最高位往后进行数位dp+记忆化
注意一下dp转移和条件的讨论即可

#include<iostream>
#include<cstdio>
#include<vector>
#include<string.h>
#include<string>
using namespace std;
const int mod=1e9+7;
#define ll long long
#define base 1000    //以1000为起点
int n;
string num;
ll dp[105][2050][2][2][2];
ll dfs(int pos,int sum,int limita,int limitb,int limit){   
//pos当前搜索位置   sum当前A与B数位差   limita A是否为上界情况  limitb B是否为上界情况  limit A小于或等于B
	if(pos>=n)
		return sum>base;
	if(dp[pos][sum][limita][limitb][limit]!=-1){
		return dp[pos][sum][limita][limitb][limit];
	}
	int up1=limita? (num[pos]-'0'):9;
	int up2=limitb? (num[pos]-'0'):9;
	ll res=0;
	for(int i=0;i<=up1;i++){
		for(int j=0;j<=up2;j++){
			if(!limit&&i>j)   //A本来=B且当前选择数i>j
				continue;
			res+=dfs(pos+1,sum+i-j,limita&&(i==up1),limitb&&(j==up2),(limit||i<j));
			res%=mod;
		}
	}
	return dp[pos][sum][limita][limitb][limit]=res;
}
int main(){
	memset(dp,-1,sizeof(dp));
	cin>>num;
	n=num.size();
	cout<<dfs(0,base,1,1,0)<<endl;
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Buyi.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值