TIOJ1387 / 1407 多重背包問題

https://tioj.ck.tp.edu.tw/problems/1387
https://tioj.ck.tp.edu.tw/problems/1407
這兩題是多重背包問題,1307測資範圍比較鬆,可以用O(NTC)的做法試試,1407就要用單調隊列優化來AC(複雜度為O(NT))。我在解1407時,因為deque放迴圈,所以吃了TLE,後來才想到要放迴圈外面,我原本是想讓它自動clear,沒想到要付出時間代價。

附上TIOJ1407的code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#include <bits/stdc++.h>
using namespace std;
const int N = 1000005;
const int M = 100005;
const int INF = 1e9;
struct Data{
int id,val;
};
int dp[N], ww[M], mm[M], cc[M];
int main(){
int n, t;
deque<Data> dq[1005];
fill(dp, dp + N, -INF);
dp[0] = 0;
cin >> n;
for(int i = 0; i < n; i++){
cin >> ww[i] >> mm[i] >> cc[i];
}
cin >> t;
for(int i = 0, w, m, c; i < n; i++){
w = ww[i]; m = mm[i]; c = cc[i];
for(int j = 0; j <= t; j++){
if(j < w){
dq[j].clear();
dq[j].push_back({j,dp[j]});
continue;
}
int id = j % w;
while(dq[id].front().id + c * w < j)dq[id].pop_front();
int tmp = dq[id].front().val + (j - dq[id].front().id) / w * m;
while(!dq[id].empty() && dq[id].back().val + (j - dq[id].back().id) / w * m <= dp[j])
dq[id].pop_back();
dq[id].push_back({j,dp[j]});
dp[j] = max(dp[j], tmp);
}
}
int ans = -INF;
for(int i = 0; i <= t; i++){
ans = max(ans, dp[i]);
}
cout << ans << '\n';
}

如果你覺得這篇文章很棒,請你不吝點讚 (゚∀゚)

Recommended Posts