LuoguP4823 [TJOI2013]拯救小矮人
阿新 • • 發佈:2020-07-16
LuoguP4823 [TJOI2013]拯救小矮人
Description
題目大意:n個人每個人有身長A和臂長B,如果滿足A1+A2+……An+Bn>=H 則第N個人可以爬出洞
怎樣安排順序使最多人爬出洞。
Solution
可以考慮一個顯然的貪心:身高+臂長越長的人越後面出去
所以按身高加臂長排序,讓越難出去的先出去。
但是因為出去是由身高加臂長兩個因素決定的
所以不代表身高加臂長長的人一定在小的人後出去
舉個例子,當H=9 如果a1 = 5 , b1 = 2 ,a2 = 2 ,b2 = 1
那麼反而要身高加腿長更小的當人梯
即需要考慮奉獻自己的情況
所以考慮DP
令DP[i]表示前面更容易走的走了i個人後剩下的最大高度
轉移方程見程式碼
#include<bits/stdc++.h> using namespace std; inline int read() { int f = 1 ,x = 0; char ch; do { ch = getchar(); if(ch == '-') f = -1; }while(ch<'0'||ch>'9'); do { x = (x<<3) + (x<<1) + ch - '0'; ch = getchar(); }while(ch>='0'&&ch<='9'); return f*x; } const int MAXN = 100000 + 10; struct ZHENGJUNSHIDASHABI { int a; int b; friend bool operator < (ZHENGJUNSHIDASHABI a1,ZHENGJUNSHIDASHABI a2) { if(a1.a+a1.b == a2.a + a2.b) returna1.a<a2.a; else return a1.a+a1.b<a2.a+a2.b; } }p[MAXN]; int n; int H; int dp[MAXN]; int main() { n = read(); for(int i=1;i<=n;i++) p[i].a = read(),p[i].b = read(),dp[0]+=p[i].a; sort(p+1,p+n+1); H = read(); for(int i=1;i<=n;i++) dp[i] = -(1<<30); for(int i=1;i<=n;i++) { for(int j=i;j>=1;j--) { if(dp[j-1] + p[i].b >= H) { dp[j] = max(dp[j] , dp[j-1] - p[i].a); } } } int res = 0; for(int i=n;i>=0;i--) if(dp[i] >= 0){res = i;break;} cout << res << endl; }