zoukankan      html  css  js  c++  java
  • 洛谷P2577 午餐

    题目

    DP或者说是递推。

    首先我们考虑一定要让吃饭慢的人排在前面,因为打饭的时间其实是固定的,所以首先要考虑吃饭慢的人先吃饭。然后再考虑两个窗口的问题。设置(dp[i][j])为前i个人在1号窗口打饭时间为j时,所用的最小的结束时间。只需知道前i个人的打饭时间,即可推出前i个人在2号窗口打饭的时间。

    然后(DP),有转移方程:
    (dp[i][j]=max(dp[i][j], sum[i]-j+data[i].b))这是最基础的式子,当前结束时间必是在1号窗口所使用的时间和在二号窗口中使用的时间中的最大值。

    (dp[i][j]=MIN{max(dp[i-1][j-data[i].a],j+data[i].b)})当前的最小结束时间肯定不会比j+data[i].b小,也不会比前一个人的结束时间快,因此需要取他们的最大值,然后更新他们的最短结束时间取最小值。

    #include <bits/stdc++.h>
    #define N 100101
    using namespace std;
    int n, ans = 2147483647, dp[N], sum[N];//dp[i][j]表示第i个人在1号窗口打饭时间为j时,所用的最小的结束时间,可以压维,
    struct dat {int a, b;}data[300];
    bool cmp(dat a, dat b){return b.b < a.b;}
    int main()
    {
    	scanf("%d", &n);
    	for (int i = 1; i <= n; i++)
    		scanf("%d%d", &data[i].a, &data[i].b);
    	sort(data + 1, data + 1 + n, cmp);//让吃饭时间长的人排在前面,简单的贪心
    	memset(dp, 123, sizeof(dp));//dp都设为最大值。
        for (int i = 1; i <= n; i++)
        	sum[i] = sum[i - 1] + data[i].a;//首先找所有人的打饭时间。
        dp[0] = 0;
        for (int i = 1; i <= n; i++)
         	for (int j = sum[i]; j; j--)//倒着枚举,可以压维。
     		{
     			if (j >= data[i].a)
    	 			dp[j] = min(dp[j], max(dp[j - data[i].a], j + data[i].b));//当前最小的结束时间一定等于当前两个窗口结束时间的最大值的最小值。 
    		 	dp[j] = max(dp[j], sum[i] - j + data[i].b);
     		}
     	for (int i = 1; i <= sum[n]; i++)
     		ans = min(ans, dp[i]);
     	printf("%d", ans);
     	return 0; 
    }
    
  • 相关阅读:
    20145204《信息安全系统设计基础》期中总结
    20145204&20145212信息安全系统实验一报告
    k8s运维记
    服务器免密登录
    非正常关闭vi编辑器产生swp文件怎么删除
    centos7 安装 python3 、docker、 docker-compose 脚本
    数据库高可用方案
    centos7安装docker-compose报错解决办法
    centos7 一键安装python3 --转发
    安装docker-compose的两种方式
  • 原文地址:https://www.cnblogs.com/liuwenyao/p/11772877.html
Copyright © 2011-2022 走看看