Title: https://www.lydsy.com/JudgeOnline/problem.php?id=1029
Of course, sort by end time, then fix or skip in order. It's the kind of "... The proof that the answer will not be "."
Think of a DP. dp[i] [j] represents the first building, a J-building, the earliest time to complete. It's a pity that n^2.
dp[I [J]=min (Dp[i-1] [j], dp[i-1 [j-1]+len[i]) (dp[i-1 [j-1]+len[i]<=t[i])
Consider this transfer. If there is j1>j2 && dp[I [J1]<dp[i] [J2], then dp[I [J2] is useless. The last to see is the largest attainable J.
The reason for preserving those little j is that they may end up early, possibly to the benefit of the latter, the transfer of the dp[I [j]=dp[i-1] [j-1]+len[i].
Should think about it more carefully. Consider only the largest j, the small j0 useful to it is actually only j0=j-1.
A new building, either directly from the largest J here to J+1, or keep J. In order to maintain J, a value of j-1 is required, and then a second dimension is obtained.
But in fact, the maintenance of J only need to "keep J" when you do not have to skip the current building, but instead of a longer time to replace the building, can be maintained!
And then it becomes the kind of greedy look. You can fix the current building, or replace one.
I thought that when now+a[i].len>a[i].t and Now-q.top () +a[i].len<=a[i].t can explain A[i].len<q.top (). It's stupid.
#include <iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<queue>using namespacestd;Const intn=150005;intN,now;structnode{intlen,t;} A[n];p riority_queue<int>Q;BOOLCMP (Node U,node v) {returnu.t<v.t;}intMain () {scanf ("%d",&N); for(intI=1; i<=n;i++) scanf ("%d%d",&a[i].len,&a[i].t); Sort (a+1, a+n+1, CMP); for(intI=1; i<=n;i++) if(now+a[i].len<=a[i].t) now+=A[i].len,q.push (A[i].len); Else if(Q.size () &&a[i].len<q.top () &&now-q.top () +a[i].len<=a[i].t)//a[i].len<q.top ()!!!Now=now-q.top () +A[i].len,q.pop (), Q.push (A[i].len); printf ("%d\n", Q.size ()); return 0;}
Bzoj 1029 [JSOI2007] construction Repair--greedy (pseudo DP)