#10:wannanewtry——6

HDU3401,列完转移方程拆分一下,正着、反着跑优先队列优化代表买或卖。初始化不大会搞……

 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 }
View Code

 

为了少一些痛苦自闭,蒟蒻只好写几道cf水题。

 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\n", i, n-i);
12                 break;
13             }
14     }
15     return 0;
16 }
854A
 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\n", min(n - k, 2*k));
13     }
14     return 0;
15 }
854B

优先队列乱模拟一下:

 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 }
853A

 

差分预处理,枚举区间:

 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 }
853B

 

BZOJ1010,斜率优化dp经典题,推式子很重要,设定不同的函数做法也会有难易区分。

 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 }
View Code

 

posted @ 2019-02-10 23:16  AlphaWA  阅读(123)  评论(0编辑  收藏  举报