「CF1154F」Shovels Shop【背包DP】
题目链接
题解
非常简单的背包。
\(f[i]\)表示购买\(i\)个物品所需要最少的花费。
不考虑免费的限制条件,那么一定是选择前\(k\)个双鞋子。
那么加入免费的条件,那么还是要挑最便宜的买。
\(g[i]\)表示购买\(i\)双鞋子能够免费最多的数量。
状态转移方程就是\(f[i]=min(f[i],f[j]+calc(i,j))\),其中\(j\in[1,i)\)
把这个\(calc(i,j)\)展开来就是\(\sum^i_{k=j+1}a[k]-\sum^{j+g[i-j]}_{k=j}a[k]\)
很明显这个式子可以用前缀和优化。
时间复杂度:\(O(nk)\)
代码
#include <bits/stdc++.h>
#define inf 0x3f3f3f3f
using namespace std;
namespace chhokmah {
#define N 200005
int f[N], g[N], a[N], sum[N];
int n, m, k;
void chhokmah() {
scanf("%d%d%d", &n, &m, &k);
for (int i = 1; i <= n; i ++) scanf("%d", &a[i]);
sort(a + 1, a + 1 + n);
for (int i = 1; i <= n; i ++) sum[i] = sum[i - 1] + a[i];
for (int i = 1, x, y; i <= m; i ++) { scanf("%d%d", &x, &y); g[x] = max(g[x], y); }
for (int i = 1; i <= k; i ++) {
f[i] = inf;
for (int j = 0; j < i; j ++) f[i] = min(f[i], f[j] + sum[i] - sum[j + g[i - j]]);
}
cout << f[k] << endl;
} }
int main() { chhokmah::chhokmah(); return 0; }

更多精彩