HDU3401,列完转移方程拆分一下,正着、反着跑优先队列优化代表买或卖。初始化不大会搞……
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 const int inf = 0x3f3f3f3f; 5 const int maxn = 2005; 6 int T, n, maxp, w; 7 int ap, bp, as, bs; 8 int f[maxn][maxn]; 9 int q[maxn], v[maxn]; 10 11 int DP() { 12 for (int j = 1; j <= maxp; j++) 13 f[0][j] = -inf; 14 for (int i = 1; i <= w+1; i++) { 15 scanf("%d%d%d%d", &ap, &bp, &as, &bs); 16 17 for (int j = 0; j <= maxp; j++) { 18 if (j <= as) f[i][j] = -j*ap; 19 else f[i][j] = -inf; 20 f[i][j] = max(f[i][j], f[i-1][j]); 21 } 22 } 23 for (int i = w+2; i <= n; i++) { 24 scanf("%d%d%d%d", &ap, &bp, &as, &bs); 25 26 int l = 1, r = 0; 27 for (int j = 0; j <= maxp; j++) { 28 f[i][j] = f[i-1][j]; 29 while (l <= r && f[i-w-1][j] + j*ap > v[r]) r--; 30 q[++r] = j; 31 v[r] = f[i-w-1][j] + j*ap; 32 33 while (l <= r && q[l] < j-as) l++; 34 if (l <= r) f[i][j] = max(f[i][j], v[l]-j*ap); 35 } 36 37 l = 1, r = 0; 38 for (int j = maxp; ~j; j--) { 39 while (l <= r && f[i-w-1][j] + j*bp > v[r]) r--; 40 q[++r] = j; 41 v[r] = f[i-w-1][j] + j*bp; 42 43 while (l <= r && q[l] > j+bs) l++; 44 if (l <= r) f[i][j] = max(f[i][j], v[l]-j*bp); 45 } 46 } 47 return f[n][0]; 48 } 49 50 int main() { 51 for (cin >> T; T; T--) { 52 cin >> n >> maxp >> w; 53 cout << DP() << endl; 54 } 55 return 0; 56 }
为了少一些痛苦自闭,蒟蒻只好写几道cf水题。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 int n; 5 6 int main() { 7 while (cin >> n) { 8 int m = n/2; 9 for (int i = m; i; i--) 10 if (__gcd(i, n-i) == 1) { 11 printf("%d %d ", i, n-i); 12 break; 13 } 14 } 15 return 0; 16 }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 int n, k; 5 6 int main() { 7 while (cin >> n >> k) { 8 if (k > 0 && k < n) 9 printf("1 "); 10 else printf("0 "); 11 12 printf("%d ", min(n - k, 2*k)); 13 } 14 return 0; 15 }
优先队列乱模拟一下:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 typedef pair<int, int> P; 5 int n, k; 6 priority_queue<P> Q; 7 set<int> minute; 8 set<int>::iterator it; 9 int v[300005]; 10 long long ans; 11 12 int main() { 13 cin >> n >> k; 14 for (int i = 1; i <= n; i++) { 15 int cost; 16 scanf("%d", &cost); 17 Q.push(P(cost, i)); 18 minute.insert(i+k); 19 } 20 21 for (int i = 1; i <= n; i++) { 22 auto t = Q.top(); Q.pop(); 23 int k1 = t.second; 24 if (k1 < k) k1 = k; 25 it = minute.lower_bound(k1); 26 v[t.second] = *it; 27 ans += (long long)(*it - t.second) * t.first; 28 minute.erase(it); 29 } 30 31 cout << ans << endl; 32 for (int i = 1; i <= n; i++) 33 printf("%d ", v[i]); 34 return 0; 35 }
差分预处理,枚举区间:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <bits/stdc++.h> 2 #define ll long long 3 #define ri readint() 4 #define gc getchar() 5 #define pb push_back 6 #define P pair<int, int> 7 using namespace std; 8 9 const ll INF = 1e13; 10 const int maxn = 100005; 11 const int maxday = 1000000; 12 13 int n, m, k; 14 ll f[maxn]; 15 ll s[maxday+5], t[maxday+5]; 16 vector<int> from[maxday+5], to[maxday+5], cost[maxday+5]; 17 18 inline int readint() { 19 int x = 0, s = 1, c = gc; 20 while (c <= 32) c = gc; 21 if (c == '-') s = -1, c = gc; 22 for (; isdigit(c); c = gc) 23 x = x*10 + c - 48; 24 return x * s; 25 } 26 27 void init(ll *x, int k) { 28 for (int i = 1; i <= n; i++) 29 f[i] = INF; 30 x[k] = INF*n; 31 } 32 33 int main() { 34 cin >> n >> m >> k; 35 for (int i = 0; i < m; i++) { 36 int day = ri, f = ri, t = ri, c = ri; 37 from[day].pb(f); 38 to[day].pb(t); 39 cost[day].pb(c); 40 } 41 42 init(s, 0); 43 for (int i = 1; i <= maxday; i++) { 44 s[i] = s[i-1]; 45 for (int j = 0; j < from[i].size(); j++) { 46 if (to[i][j] == 0 && cost[i][j] < f[from[i][j]]) { 47 s[i] -= f[from[i][j]] - cost[i][j]; 48 f[from[i][j]] = cost[i][j]; 49 } 50 } 51 } 52 init(t, maxday+1); 53 for (int i = maxday; i; i--) { 54 t[i] = t[i+1]; 55 for (int j = 0; j < from[i].size(); j++) { 56 if (from[i][j] == 0 && cost[i][j] < f[to[i][j]]) { 57 t[i] -= f[to[i][j]] - cost[i][j]; 58 f[to[i][j]] = cost[i][j]; 59 } 60 } 61 } 62 63 ll ans = INF; 64 for (int i = 2; i + k <= maxday; i++) 65 ans = min(ans, s[i-1] + t[i+k]); 66 if (ans > 1e12) puts("-1"); 67 else cout << ans << endl; 68 69 return 0; 70 }
BZOJ1010,斜率优化dp经典题,推式子很重要,设定不同的函数做法也会有难易区分。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <bits/stdc++.h> 2 #define db double 3 #define maxn 50005 4 using namespace std; 5 6 int n, L; 7 int head, tail; 8 int q[maxn]; 9 db sum[maxn], f[maxn]; 10 11 db sqr(db x) { 12 return x * x; 13 } 14 db a(int i) {//斜率单调的 15 return sum[i] + i; 16 } 17 db b(int i) { 18 return sum[i] + i + L + 1; 19 } 20 db Y(int i) { 21 return f[i] + sqr(b(i)); 22 } 23 db slope(int i, int j) { 24 return (Y(j) - Y(i)) / (b(j) - b(i)); 25 } 26 27 int main() { 28 cin >> n >> L; 29 for (int i = 1; i <= n; i++) { 30 scanf("%lf", &sum[i]); 31 sum[i] += sum[i-1]; 32 } 33 head = 1, tail = 1; 34 for (int i = 1; i <= n; i++) { 35 while (head < tail && slope(q[head], q[head+1]) < 2*a(i)) head++; 36 f[i] = f[q[head]] + sqr(a(i) - b(q[head])); 37 38 while (head < tail && slope(q[tail-1], q[tail]) > slope(q[tail-1], i)) tail--; 39 q[++tail] = i; 40 } 41 cout << fixed << setprecision(0) << f[n] << endl; 42 return 0; 43 }