BZOJ3174 TJOI2013 拯救小矮人 貪心、DP
阿新 • • 發佈:2019-03-24
能力 的人 include 個人 cout getchar() fin algorithm iomanip
個人跑不跑即可。
傳送門
原問題等價於:先給\(n\)個人排好順序、疊在一起,然後從頂往底能走即走,問最多能走多少人
註意到一個問題:如果存在兩個人\(i,j\)滿足\(a_i + b_i < a_j + b_j\)且\(i,j\)兩個人都要逃跑,那麽\(j\)會在\(i\)之後跑,因為\(i\)的逃跑能力沒有\(j\)強,如果\(j\)先逃跑了,那麽\(i\)就有可能沒法逃跑。
所以對於所有人按照\(a_i + b_i\)從小到大排序,那麽逃跑順序一定是升序的。
最後計算方案使用DP。設\(f_{i,j}\)表示考慮了前\(i\)個人、跑了\(j\)個人之後剩下所有人搭成的人梯的最高高度,轉移考慮第\(i\)
#include<iostream> #include<cstdio> #include<cstdlib> #include<ctime> #include<cctype> #include<algorithm> #include<cstring> #include<iomanip> #include<queue> #include<map> #include<set> #include<bitset> #include<vector> #include<stack> #include<cmath> //This code is written by Itst using namespace std; inline int read(){ int a = 0; char c = getchar(); bool f = 0; while(!isdigit(c) && c != EOF){ if(c == '-') f = 1; c = getchar(); } if(c == EOF) exit(0); while(isdigit(c)){ a = a * 10 + c - 48; c = getchar(); } return f ? -a : a; } #define PII pair < int , int > #define st first #define nd second int dp[2003][2003] , N , H; vector < PII > peo; bool cmp(PII a , PII b){return a.st + a.nd < b.st + b.nd;} signed main(){ #ifndef ONLINE_JUDGE freopen("in","r",stdin); //freopen("out","w",stdout); #endif N = read(); int sum = 0; for(int i = 1 ; i <= N ; ++i){ int x = read() , y = read(); peo.push_back(PII(x , y)); sum += x; } H = read(); sort(peo.begin() , peo.end() , cmp); int maxN = 0; dp[0][0] = sum; for(int i = 1 ; i <= N ; ++i){ PII t = peo[i - 1]; for(int j = maxN ; j >= 0 ; --j){ if(dp[i - 1][j] + t.nd >= H){ dp[i][j + 1] = max(dp[i][j + 1] , dp[i - 1][j] - t.st); if(j == maxN) ++maxN; } dp[i][j] = dp[i - 1][j]; } } cout << maxN; return 0; }
BZOJ3174 TJOI2013 拯救小矮人 貪心、DP