1. 程式人生 > >「CF1154F」Shovels Shop【背包DP】

「CF1154F」Shovels Shop【背包DP】

max 其中 href bit 鞋子 題目 cal std clas

題目鏈接

【洛谷傳送門】

題解

非常簡單的背包。
\(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; }

「CF1154F」Shovels Shop【背包DP】