2025/5/4集训(下午)
dp优化:
1.优化状态(降维)
2.优化转移:
数据结构(啊啊啊啊啊啊啊啊该死的数据结构!!!!!!!)
1.主要用线段树(啊啊啊听不懂)
...
例题:
例什么例,种地去!!!
好嘞~
(此处本来有写Problem1的代码,但是我没跟上没打完TAT)
收尾!数位dp
数位dp:
在l~r之间满足条件的数有多少个,和是多少.
1.变成sigma(r, i = 0, f(i))-sigma(l-1, i = 0, f(i));
sigma(x, y, z) =
y
Σz
x
那么:
f[i][0/1]:yn~yi,已经填了的部分<(0)还是=(1)x
int f[i][0/1];//同正文
int g[i][0/1];//同上,但是方案数
int dp(int x_){//求0~x_的各位数字之和
//O(logx)(非常快!!!!!!!!!!!!!!!!!!!!!!!!!)
int n = 0;
while (x_ != 0){//取出x_的数位之和
n++;
x[n] = x_%10;
x_ /= 10;
}
memset(f, 0, sizeof(f));//2次dp要清空
memset(g, 0, sizeof(g));
//开始dp
f[n+1][1] = 0, g[n+1][1] = 1;
for (int i = n; i >= 1; i--){
for (int j = 0; j < 2; j++){
if (f[i+1][j]){//从这个开始转移,
int up = 9;
if (j == 1) up = x[i];
for (int k = 0; k <= up; k++){//在yi填k
f[i][(j == 1) && (k == up)] += f[i+1][j]+g[i+1][j]*k;
g[i][(j == 1) && (k == up)] += g[i+1][j];
}
}
}
}
return f[1][0]+f[1][1];
}
int main(){
int l, r;
cin >> l >> r;
cout << dp(r)-dp(l-1);
}
浙公网安备 33010602011771号