2020牛客多校六 H. Harmony Pairs (数位dp)

题意:求1<=A<=B<=N,满足S(A)>S(B)的(A, B)对数,S是数位和。
在这里插入图片描述

题解:数位dp
看范围,数位dp。

d p [ p o s ] [ d ] [ f 0 ] [ f 1 ] dp[pos][d][f0][f1] dp[pos][d][f0][f1]:表示dfs到当前pos,之前的位数差为d,B与N的关系为f0,A与B的关系为f1。具体见注释。

接着裸的数位dp。差可能为负,d右移1000即可。

#define _CRT_SECURE_NO_WARNINGS
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define ll long long
using namespace std;
const int mod = 1e9 + 7;
const int ini = 1000;
char s[111];
int a[111], dp[111][2111][2][2];
int dfs(int pos, int d, int f0, int f1) {
	if (pos == -1) return d > ini;
	if (dp[pos][d][f0][f1] != -1) return dp[pos][d][f0][f1];
	int up = f0 ? a[pos] : 9;   //B的之前位都与n之前位相同
	int ans = 0;
	for (int i = 0; i <= up; i++) {       //B
		int up2 = f1 ? i : 9;             //A的之前位都与B之前位相同
		for (int j = 0; j <= up2; j++) {  //A
			ans = (ans + dfs(pos - 1, d + j - i, f0 && (i == up), f1 && (j == up2))) % mod;
		}
	}
	dp[pos][d][f0][f1] = ans;
	return ans;
}
int solve() {
	int len = strlen(s);
	for (int i = 0; i < len; i++) {
		a[len - i - 1] = s[i] - 48;
	}
	return dfs(len - 1, ini, 1, 1);
}
int main() {
	memset(dp, -1, sizeof(dp));
	scanf("%s", s);
	cout << solve();
	return 0;
}

你可能感兴趣的:(#,数位dp)