题解:P14644 [POI 2025/2026 #1] 表达式 / Arithmetic expression
__Raincoat__ · · 题解
题解:P14644 [POI 2025/2026 #1] 表达式 / Arithmetic expression
读题
发现要输出
状态
这道题用答案作为状态即可。用
转移
题目明显给出了两种转移方式:
- 加法:
f_i = \min _{1 \le j < i} (f_{i-j} + f_j + b) 。 - 乘法:
f_i = \min _{1 \le j < i} (f_{i/j} + f_j + c) ,理论上来说,这样写不会有很大问题,但是为了逻辑严谨:- 我们把
j 的下界定为2 ,不然会使用自己更新,这在逻辑上不合理。 - 只在
i | j 时更新,因为非整数状态未定义(尽管 C++ 会自动帮你向下取整)。
- 我们把
Code
#include <bits/stdc++.h>
#define int long long
using namespace std;
constexpr int maxn = 3e3+7,inf = LLONG_MAX;
int n,a,b,c,f[maxn];
signed main(){
cin.tie(0)->sync_with_stdio(0);
cin>>n>>a>>b>>c;
for(int i=1;i<=n;i++)f[i] = inf;f[1] = a;
for(int i=1;i<=n;i++){
for(int j=1;j<i;j++)f[i] = min(f[i],f[i-j] + f[j] + b);
for(int j=2;j<i;j++)if(i%j == 0)f[i] = min(f[i],f[i/j] + f[j] + c);
cout<<f[i]<<' ';
}
return 0;
}