• [BZOJ1899]Lunch 午餐(DP)


    [BZOJ1899]

    首先有个很贪心的思路,吃饭时间长的最先打饭为最优,所以开始先排个序

    然后考虑DP,我们不需要知道某个人在哪个对,只要关注总的时间就行了

    肯定需要一维表示当前同学编号,还需要表示某个窗口的打饭时间,如果知道其中一个窗口,另一个也可以知道,所以一维就行

    那么用f[i][j]表示前i个同学,第一个窗口打饭总时间为j时的答案

    s[i]表示排序后前打饭时间前缀和,a表示打饭时间,b表示吃饭时间

    1. 当前同学放二号窗口,f[i][j]=min{f[i][j],max(f[i-1][j],sum[i-1]-j+A[i].a+A[i].b)}
    2. 放1号窗口,f[i][j]=min{f[i][j],max(f[i-1][j-A[i].a],j+A[i].b)}

    Code

    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    #define N 210 
    using namespace std;
    
    struct info{
    	int a,b;
    	friend bool operator <(info a,info b){
    		return a.b>b.b;
    	}
    }A[N];
    int n,Ans,s[N],f[N][N*N],sum;
    
    inline int read(){
        int x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    
    int main(){
    	n=read();
    	for(int i=1;i<=n;++i) A[i].a=read(),A[i].b=read();
    	sort(A+1,A+n+1);
    	for(int i=1;i<=n;++i) s[i]=s[i-1]+A[i].a;
    	memset(f,0x3f,sizeof(f));f[0][0]=0;
    	for(int i=1;i<=n;++i)
    		for(int j=0;j<=s[i];++j){
    			f[i][j]=min(f[i][j],max(f[i-1][j],s[i-1]-j+A[i].a+A[i].b));
    			if(j>=A[i].a) f[i][j]=min(f[i][j],max(f[i-1][j-A[i].a],j+A[i].b));
    		}
    	Ans=1e9;
    	for(int i=0;i<=s[n];++i) Ans=min(Ans,f[n][i]);
    	printf("%d
    ",Ans);
    	return 0;
    }
    
  • 相关阅读:
    性能测试二十四:环境部署之Redis多实例部署
    性能测试二十三:环境部署之Redis安装和配置
    性能测试二十二:环境部署之Nginx
    性能测试二十一:环境部署之mysql
    性能测试二十:环境部署之Tomcat多实例部署+日志监控
    性能测试十九:jmeter参数优化+排错
    Zookeeper学习
    Zookeeper学习
    Zookeeper学习
    Hadoop Balancer源码解读
  • 原文地址:https://www.cnblogs.com/void-f/p/9025528.html
Copyright © 2020-2023  润新知