洛谷P1280题解
简单DP。
首先分析从前往后的。那么显然当前状态就是当前时间最少工作的时间。
然后我列了一张表。
i 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
f[i] 1 2 2 3 4 5 6 7 7 7 8 9 10 11 11
似乎没规律?
这时明显想到要对数据进行排序。亲测没用。
于是想到倒推。
还是一张表。
i 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1
f[i] 1 2 3 3 3 3 3 3 4 4 4 4 4 4 4
似乎没规律?
这时明显想到要对数据进行排序。
显然,要以开始时间倒序排序。
样例排出来是这样的:
11 | 5 |
8 | 5 |
8 | 1 |
4 | 11 |
1 | 6 |
1 | 2 |
显然,如果时间 i 没有新开始的任务,那么 f[i] 就是 f[i + 1] + 1。
否则,f[i] = max{f[i + t[j]]}。
这时重新修一下表格。
i 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1
f[i]1 2 3 4 1 = f[15] 2 3 3 = max(f[13],f[9]) 4 5 6 1 = f[15] 2 3 4
突然发现 f 数组的意义改变了!但答案是对的就行了。
表格中未注明的就是 f[i + 1] + 1 。
代码:
1 #include<stdio.h>
2 #include<algorithm>
3 #define reg register
4 #define ri reg int
5 #define rep(i, x, y) for(ri i = x; i <= y; ++i)
6 #define nrep(i, x, y) for(ri i = x; i >= y; --i)
7 #define DEBUG 1
8 #define ll long long
9 #define il inline
10 #define max(i, j) (i) > (j) ? (i) : (j)
11 #define min(i, j) (i) < (j) ? (i) : (j)
12 #define read(i) io.READ(i)
13 #define print(i) io.WRITE(i)
14 #define push(i) io.PUSH(i)
15 struct IO {
16 #define MAXSIZE (1 << 20)
17 #define isdigit(x) (x >= '0' && x <= '9')
18 char buf[MAXSIZE], *p1, *p2;
19 char pbuf[MAXSIZE], *pp;
20 #if DEBUG
21 #else
22 IO() : p1(buf), p2(buf), pp(pbuf) {}
23 ~IO() {
24 fwrite(pbuf, 1, pp - pbuf, stdout);
25 }
26 #endif
27 inline char gc() {
28 #if DEBUG
29 return getchar();
30 #endif
31 if(p1 == p2)
32 p2 = (p1 = buf) + fread(buf, 1, MAXSIZE, stdin);
33 return p1 == p2 ? ' ' : *p1++;
34 }
35 inline bool blank(char ch) {
36 return ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t';
37 }
38 template <class T>
39 inline void READ(T &x) {
40 register double tmp = 1;
41 register bool sign = 0;
42 x = 0;
43 register char ch = gc();
44 for(; !isdigit(ch); ch = gc())
45 if(ch == '-') sign = 1;
46 for(; isdigit(ch); ch = gc())
47 x = x * 10 + (ch - '0');
48 if(ch == '.')
49 for(ch = gc(); isdigit(ch); ch = gc())
50 tmp /= 10.0, x += tmp * (ch - '0');
51 if(sign) x = -x;
52 }
53 inline void READ(char *s) {
54 register char ch = gc();
55 for(; blank(ch); ch = gc());
56 for(; !blank(ch); ch = gc())
57 *s++ = ch;
58 *s = 0;
59 }
60 inline void READ(char &c) {
61 for(c = gc(); blank(c); c = gc());
62 }
63 inline void PUSH(const char &c) {
64 #if DEBUG
65 putchar(c);
66 #else
67 if(pp - pbuf == MAXSIZE) {
68 fwrite(pbuf, 1, MAXSIZE, stdout);
69 pp = pbuf;
70 }
71 *pp++ = c;
72 #endif
73 }
74 template <class T>
75 inline void WRITE(T x) {
76 if(x < 0) {
77 x = -x;
78 PUSH('-');
79 }
80 static T sta[35];
81 T top = 0;
82 do {
83 sta[top++] = x % 10;
84 x /= 10;
85 }while(x);
86 while(top)
87 PUSH(sta[--top] + '0');
88 }
89 template <class T>
90 inline void WRITE(T x, char lastChar) {
91 WRITE(x);
92 PUSH(lastChar);
93 }
94 } io;
95 int n, k;
96 int f[10010], s[10010];
97 struct work {
98 int p, t;
99 } w[10010];
100 int cmp(work i, work j) {
101 return i.p > j.p;
102 }
103 int main() {
104 read(n), read(k);
105 rep(i, 0, k - 1) read(w[i].p), read(w[i].t), ++s[w[i].p];
106 std::sort(w, w + k, cmp);
107 ri num = 0;
108 nrep(i, n, 1) {
109 if(s[i] == 0) f[i] = f[i + 1] + 1;
110 else rep(j, 0, s[i] - 1) {
111 if(f[i + w[num].t] > f[i])
112 f[i] = f[i + w[num].t];
113 ++num;
114 }
115 }
116 print(f[1]);
117 return 0;
118 }
没了。