尼克的任務
阿新 • • 發佈:2018-10-27
結束 cstring ring putchar get bool \n name font
傳送門
這道題雖然很基礎但是也不是很好想……
我們一開始會想,用dp[i]表示前i分鐘最大休息時間,之後你就完全不知道怎麽轉移了。
阻礙你轉移的關鍵問題在於,你不知道後面會發生什麽,但是如果從後面倒著DP的話就可以了。因為這樣的話,你後面的過程相當於是已知的。我們只要在記錄一下以這個點為開始的工作有多少,之後直接從那個工作的結束轉移過來即可。如果沒工作,直接從上一個位置轉移即可。
看一下代碼。
#include<cstdio> #include<algorithm> #include<cstring> #include<iostream> #include<cmath> #include<set> #include<queue> #define rep(i,a,n) for(int i = a;i <= n;i++) #define per(i,n,a) for(int i = n;i >= a;i--) #define enter putchar(‘\n‘) using namespace std; typedef long long ll; const int M = 20005; const int INF = 1000000009; int read() { int ans = 0,op = 1;char ch = getchar(); while(ch < ‘0‘ || ch > ‘9‘) { if(ch == ‘-‘) op = -1; ch = getchar(); } while(ch >= ‘0‘ && ch <= ‘9‘) { ans *= 10; ans += ch - ‘0‘; ch = getchar(); } return ans * op; } struct mis { int p,t; bool operator < (constmis &g) const { return p > g.p; } }a[M]; int n,k,sum[M],dp[M],cnt = 1; int main() { n = read(),k = read(); rep(i,1,k) a[i].p = read(),a[i].t = read(),sum[a[i].p]++; sort(a+1,a+1+k); per(i,n,1) { if(!sum[i]) dp[i] = dp[i+1] + 1; else { rep(j,1,sum[i]) dp[i] = max(dp[i + a[cnt].t],dp[i]),cnt++; } } printf("%d\n",dp[1]); return 0; }
尼克的任務