为什么这个题目不需要考虑前导零的情况
  • 板块P1831 杠杆数
  • 楼主CuteChat
  • 当前回复6
  • 已保存回复6
  • 发布时间2024/1/19 19:37
  • 上次更新2024/1/19 22:01:05
查看原帖
为什么这个题目不需要考虑前导零的情况
726525
CuteChat楼主2024/1/19 19:37

我的意思是,对于支点之前的位置,必须有一个有效数位(就不能全都是 0)。这个东西考虑了反而是错误的,为什么?

AC:

long long l, r;
int d[20], top; // d 表示每个数位,top 表示是为长度
long long f[21][21][5001][2][2]; // dp
// f[pos][zd][sum][limited][zero]:
// pos:当前的数位
// zd:支点
// sum:力矩和
// limited:放满没有,放满就是 0,没有就是 1
// zero:之前有没有非零数字
long long solve(int pos, int zd, int sum, int limited, int zero) {
	if (pos == top + 1) return sum == 0;
	if (f[pos][zd][sum + 2000][limited][zero] != -1) return f[pos][zd][sum + 2000][limited][zero];
	long long ans = 0;
	for (int i = 0; i <= max(limited * 9, d[pos]); ++i) { // 这里从零开始
		ans += solve(pos + 1, zd, sum + (pos - zd) * i, limited || (i != d[pos]), zero || (i != 0));
	}
	return f[pos][zd][sum + 2000][limited][zero] = ans;
}

WA:

long long solve(int pos, int zd, int sum, int limited, int zero) {
	if (pos == top + 1) return sum == 0;
	if (f[pos][zd][sum + 2000][limited][zero] != -1) return f[pos][zd][sum + 2000][limited][zero];
	long long ans = 0;
	for (int i = max(0, (int)(!zero && pos == zd)); i <= max(limited * 9, d[pos]); ++i) { // 如果之前都是零且目前这一位是支点,从 1 开始。
		ans += solve(pos + 1, zd, sum + (pos - zd) * i, limited || (i != d[pos]), zero || (i != 0));
	}
	return f[pos][zd][sum + 2000][limited][zero] = ans;
}

刚学数位 DP,不太理解。

2024/1/19 19:37
加载中...