题目链接
动态规划转化成 DAG 然后拓扑求解的思路
虽然很简单不过感觉这个新思路会很有用!
如果两个事件互不影响并且有先后关系,就可以连一条有向边,跑最长路可以得到最后的最优解
实际上这还是个背包……
1 #include <queue> 2 #include <cstdio> 3 #include <cctype> 4 #include <cstring> 5 #include <iostream> 6 #include <algorithm> 7 using namespace std; 8 9 const int maxn = 1000 + 10; 10 int n, m, r, head[maxn], dis[maxn], in_deg[maxn], edge_num, ans; 11 12 struct Segment { 13 int lef, rig, enr; 14 inline bool operator < (const Segment &x) const{ return this->rig < x.rig; } 15 } seg[maxn]; 16 17 struct Edge { int v, nxt; } edge[maxn * maxn]; 18 19 inline int read() { 20 register char ch = 0; register int w = 0, x = 0; 21 while( !isdigit(ch) ) w |= (ch == '-'),ch = getchar(); 22 while( isdigit(ch) ) x = (x * 10) + (ch ^ 48), ch = getchar(); 23 return w ? -x : x; 24 } 25 26 inline void Add_edge(int u, int v) { 27 edge[++edge_num].v = v; 28 edge[edge_num].nxt = head[u], head[u] = edge_num; 29 } 30 31 inline void Breath_fs() { 32 queue<int> q; 33 for(int i = 1; i <= m; ++i) dis[i] = seg[i].enr; 34 for(int i = 1; i <= m; ++i) if( !in_deg[i] ) q.push(i); 35 while( !q.empty() ) { 36 int x = q.front(); q.pop(); 37 for(int i = head[x]; i; i = edge[i].nxt) { 38 if( dis[edge[i].v] < dis[x] + seg[edge[i].v].enr ) 39 dis[edge[i].v] = dis[x] + seg[edge[i].v].enr; 40 if( --in_deg[edge[i].v] == 0 ) q.push(edge[i].v); 41 } 42 } 43 } 44 45 int main(int argc, char const *argv[]) 46 { 47 freopen("nanjolno.in", "r", stdin); 48 freopen("nanjolno.out", "w", stdout); 49 50 scanf("%d%d%d", &n, &m, &r); 51 for(int i = 1; i <= m; ++i) 52 seg[i].lef = read(), seg[i].rig = read() + r, seg[i].enr = read(); 53 sort(seg + 1, seg + m + 1), ans = 0; 54 for(int i = 1; i <= m; ++i) for(int j = i + 1; j <= m; ++j) 55 if( seg[i].rig <= seg[j].lef ) Add_edge(i, j), ++in_deg[j]; 56 Breath_fs(); 57 for(int i = 1; i <= m; ++i) ans = max(ans, dis[i]); 58 printf("%d ", ans); 59 60 fclose(stdin), fclose(stdout); 61 return 0; 62 }
—— 冬天来了 —— 那是悲喜交加,永远的瞬间。