[bzoj3174] 拯救小矮人
题意:N个小矮人被困在了一个高度为h的坑里,每个人都有一定的身高a_i和臂长b_i,小矮人可以站在别人的肩膀上,若a1+a2+...+ak+bk>=h,那么最上面的那个小矮人就可以逃跑,求怎样安排逃跑的顺序,使得尽量多的小矮人逃跑
题解:
贪心+dp
首先按身高加臂长sort(这种有两个代价的题是不是都是这个套路......,并不知道为什么......)
然后dp[i]表示i个人逃跑后剩下人的最大高度,这里好像不需要考虑臂长......,感性理解下就是下面的人越高,那么对上面的人贡献越大,所以出去的人就更多吧......
dp的时候更新最多逃出的人数
1 #include<iostream> 2 #include<cstdio> 3 #include<cstdlib> 4 #include<cstring> 5 #include<algorithm> 6 #include<cmath> 7 #define ll long long 8 using namespace std; 9 10 const int N = 2010; 11 12 int dp[N]; 13 14 struct Node { 15 int a,b; 16 bool operator < (const Node &x) const { 17 return a+b<x.a+x.b; 18 } 19 }p[N]; 20 21 int gi() { 22 int x=0,o=1; char ch=getchar(); 23 while(ch!='-' && (ch<'0' || ch>'9')) ch=getchar(); 24 if(ch=='-') o=-1,ch=getchar(); 25 while(ch>='0' && ch<='9') x=x*10+ch-'0',ch=getchar(); 26 return o*x; 27 } 28 29 int main() { 30 int n=gi(),h,m; 31 memset(dp,-1,sizeof(dp)); 32 dp[0]=0; 33 for(int i=1; i<=n; i++) { 34 p[i].a=gi(),p[i].b=gi(); 35 dp[0]+=p[i].a; 36 } 37 sort(p+1,p+n+1); 38 h=gi(),m=0; 39 for(int i=1; i<=n; i++) { 40 for(int j=m; j>=0; j--) { 41 if(dp[j]+p[i].b>=h) dp[j+1]=max(dp[j+1],dp[j]-p[i].a); 42 } 43 if(dp[m+1]>=0) m++;//dp[m+1]>=0时,一定是在dp[m]+p[i].b满足条件的情况下被转移,所以第j+1个一定可以逃出去 44 } 45 printf("%d\n", m); 46 return 0; 47 } 48 //排序,能力强的放在后面,带有贪心的性质? 49 //只需要保证身高最大,不用关心手长?