• ZJOI2005 午餐


    题目传送门

    嗯……我承认我看了题解,不过好歹有了点自己的思路,大约蒙出来了(30\%)(个人感觉)……

    学会(DP),任重而道远啊!


    Step1.贪心排序

    先将每个人按吃饭的快慢排序,然后再进行(DP)
    稍微证明一下这个贪心吧

    证明

    设两个人排队和吃饭的时间分别为(a_1,b_1)(a_2,b_2), 且(b_1 > b_2),那么(1)同学在前时,所花费的总时间为((a_1+b_1)+(a_2+b_2-b_1))(因为(1)同学吃饭的时间和(2)同学打饭并吃饭的时间是重叠的,所以要减去)
    化简后为(a_1+a_2+b_2)
    同理,如果(2)同学在前,总时间为(a_1+a_2+b_1)
    因为(b_1 > b_2),所以(1)同学在前时花费的总时间少

    当然,如果(b_1 geq a_2+b_2)时,((a_1+b_1)+(a_2+b_2-b_1))化简后应为(a_1+b_1)(因为不可能存在负数时间)
    但即使这样,(1)同学在前仍然更优,因为(a_1+b_1)显然(<a_1+a_2+b_1)

    Step2.DP

    状态

    f[i][j]表示前(i)个人在(1)号窗口排队打饭的时间为(j)时,吃完饭的时间

    转移方程

    • 当第(i)个人在(1)号窗口打饭时
    if(p[i].a<=j) f[i][j]=min(f[i][j],max(f[i-1][j-p[i].a],j+p[i].b));
    

    因为全部吃完饭的时刻为最后一个人吃完饭的时刻,即(max { i)同学打完饭的时间(+i)同学吃饭的时间()),而新加进来的这名同学有可能是最后一个吃完的,所以要max(f[i-1][j-p[i].a],j+p[i].b)),即在加这位同学之前的最晚时间和这位同学吃完饭的时间中取一个最大值。

    • 当第(i)个人在(2)号窗口打饭时
    f[i][j]=min(f[i][j],max(f[i-1][j],suma[i]-j+p[i].b));
    

    (max)函数同理,suma[i]表示前(i)位同学打饭所花的时间

    Code

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    int read(){
    	int k=0; char c=getchar();
    	while(c<'0'||c>'9') c=getchar();
    	while(c>='0'&&c<='9')
    	  k=k*10+c-48, c=getchar();
    	return k;
    }
    struct zzz{
    	int a,b;
    }p[210];
    bool cmp(zzz x,zzz y){
    	return x.b > y.b;
    }
    int f[210][40010],f2[210],ti[210][210],suma[210];
    int main(){
    	int n=read();
    	for(int i=1;i<=n;i++)
    	  p[i].a=read(),p[i].b=read();
    	sort(p+1,p+n+1,cmp);
    	for(int i=1;i<=n;i++)
    	  suma[i]=suma[i-1]+p[i].a;
    	memset(f,127,sizeof(f));
    	f[0][0]=0;
    	for(int i=1;i<=n;i++){
    		for(int j=1;j<=suma[i];j++){
    			if(p[i].a<=j) f[i][j]=min(f[i][j],max(f[i-1][j-p[i].a],j+p[i].b));
    			f[i][j]=min(f[i][j],max(f[i-1][j],suma[i]-j+p[i].b));
    		}
    	}
    	int ans=2147483647;
    	for(int i=1;i<=suma[n];i++)
    	  ans=min(ans,f[n][i]);
    	cout<<ans;
    	return 0;
    }
    
  • 相关阅读:
    python爬虫统计上证指数周、月涨跌现象
    python每日一题:采用正则表达式,beautifulsoap,xpath爬取网站数据
    谈股市与月份的关系
    python之正则表达式
    python每日一题:使用代理服务器爬虫
    python之cookie使用
    python每日一题:爬虫入门之利用xpath查找网页元素节点
    python每日一题:制作网页,与女朋友的点点滴滴
    【Java基础】Java11 新特性
    【Java基础】Java10 新特性
  • 原文地址:https://www.cnblogs.com/morslin/p/11855021.html
Copyright © 2020-2023  润新知