zoukankan      html  css  js  c++  java
  • HDU 4314 Contest 2

    可以知道,逃出的人中,最后一个应当是A+B最长的,这是很容易发现的。那么,最选逃出去的必定是A+B最短的。这符合最优。

    于是,可以把各小矮人按A+B的和由大到小排序。定义DP[i][j]为i个人中逃出了j个人至少需要“之前”的留在井中的未逃出去的小矮人的高度和。注意这个值是可以为负数的,是负数,则证明需要之前有人留下,这些i个人足可以把j个人送出去。

    那么,有DP[i][j]=min{dp[i-1][j]-a[i],max(dp[i-1][j-1],H-sumA[i]-b[i])}。

    解释一下递推方程,当第i个人未逃出去时,则第i个人留下,即需要满足dp[i-1][j]的人的高度减去第i个的高度。显而易见。

    当第i个人逃出去时,为什么需要max(dp[i-1][j-1],H-sumA[i]-b[i])。因为前i-1个人逃出去j-1个(i必定最先逃出)的A高度未必一定满足使第i个人逃出去的高度(最先逃出),而若H-sumA[i]-b[i]的高度能使第i个人逃出去,则必定满足后j-1个人逃出。因为第i个是最先逃出的。

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    using namespace std;
    
    int dp[2010];
    struct dwarf{
    	int a,b;
    	int sum;
    }dw[2010];
    int sumA[2010];
    bool cmp(dwarf a,dwarf b){
    	if(a.sum>b.sum)
    	 return true;
    	 return false;
    }
    
    int main(){
    	int n,H;
    	while(scanf("%d",&n)!=EOF){
    		for(int i=1;i<=n;i++){
    			scanf("%d%d",&dw[i].a,&dw[i].b);
    			dw[i].sum=dw[i].a+dw[i].b;
    		}
    		scanf("%d",&H);
    		sort(dw+1,dw+1+n,cmp);
    		sumA[0]=0;
    		for(int i=1;i<=n;i++){
    			dp[i]=(1<<30);
    			sumA[i]=sumA[i-1]+dw[i].a;
    		}
    		for(int i=1;i<=n;i++){
    			for(int j=i;j>=1;j--){
    				dp[j]=min(dp[j]-dw[i].a,max(dp[j-1],H-dw[i].b-sumA[i]));
    			}
    		}
    		int k=0;
    		for(int i=1;i<=n;i++)
    		if(dp[i]<=0)
    		k=i;
    		printf("%d
    ",k);
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    大数据下的质量体系建设
    快速打造属于你的接口自动化测试框架
    测试环境问题排查的那些事儿
    100个任务,用多机实现
    shell 在一个文件中查找数字
    shell中的awk使用
    shell怎么实现多进程
    删除字符串S1中的子串S2
    C++11的新特性
    C++里面普通指针怎么转换成智能指针
  • 原文地址:https://www.cnblogs.com/jie-dcai/p/4067223.html
Copyright © 2011-2022 走看看