zoukankan      html  css  js  c++  java
  • [ZJOI2005]午餐

    [ZJOI2005]午餐

    题面-洛谷P2577

    思路

    如果题中只有一个窗口,那么此题就是一道贪心水题(接水),显然贪心策略是让吃饭久的人先吃。但是此题有两个窗口,所以贪心后,需要动态规划决定让第(i)个人去第一或第二窗口吃饭。

    dp状态(dp[i][j])表示到第(i)个人,第一个窗口已排队总时间(j)时,最晚吃完饭的时间。而又因为到第(i)个人时,排队总时间可以前缀和预处理出(sum[i]),所以第二个窗口已排队总时间就是(sum[i]-j)

    dp转移,第(i)个人去第一个窗口

    [dp[i][j]=MIN(MAX(dp[i-1][j-a[i].a], j+a[i].b), dp[i][j]) ]

    去第二个窗口

    [dp[i][j]=MIN(MAX(dp[i-1][j], sum[i]-j+a[i].b), dp[i][j]) ]

    因为(dp)存的是最晚时间,所以可以根据上一个(dp​)状态推出当前这个人,是否可以在上个一个人吃饭时,就打饭+吃饭完成。

    代码

    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    #define MAXN 220
    #define MAX(A,B) ((A)>(B)?(A):(B))
    #define MIN(A,B) ((A)<(B)?(A):(B))
    using namespace std;
    int n,sum[MAXN],ans=0x3f3f3f3f;
    int dp[MAXN][MAXN*MAXN];
    struct nod{
        int a,b;
        bool operator < (const nod &m){
            return b > m.b;
        }
    } a[MAXN];
    int main()
    {
        scanf("%d", &n);
        for(int i=1;i<=n;++i)
            scanf("%d %d", &a[i].a, &a[i].b);
        sort(a+1, a+1+n);
        for(int i=1;i<=n;++i)
            sum[i]=sum[i-1]+a[i].a;
        memset(dp, 0x3f, sizeof(dp));
        dp[0][0]=0;
        for(int i=1;i<=n;++i)
        for(register int j=0;j<=sum[i];++j){
            if(j-a[i].a>=0) dp[i][j]=MIN(MAX(dp[i-1][j-a[i].a], j+a[i].b), dp[i][j]); // 去一号
            dp[i][j]=MIN(MAX(dp[i-1][j], sum[i]-j+a[i].b), dp[i][j]); // 去二号
        }
        for(int i=0;i<=sum[n];++i)
            ans=MIN(ans, dp[n][i]);
        printf("%d", ans);
        return 0;
    }
    
  • 相关阅读:
    Docker For Windows | Setting Up Docker On Windows
    10款游戏的设计分析
    游戏中的沉浸(Flow in Games)
    游戏中运用了人工智能、机器学习等智能算法的思考
    虚幻4的智能指针
    linux下查看已安装的软件与卸载
    Centos7.2下安装mysql5.7,使用rpm包安装
    VMware 安装 CentOS7
    并发之痛 Thread,Goroutine,Actor
    Creating and using a blendspace in c++
  • 原文地址:https://www.cnblogs.com/santiego/p/10856207.html
Copyright © 2011-2022 走看看