• HDOJ 4128 Helporelse(DP)


    题意:从时间0开始需要接待n个人,对于每个人,可以选择接待或者跳过,若接待,花费的时间是T+ai ,T为开始接待这个人的时间,若跳过则罚时bi ,现给定总时间K,问你最多能接待多少人?
    分析:如果接待的人的集合确定了,那你一定先接待 bi 小的人再接待 bi 大的人,所以我们可以先按 b 从小到大排序。定义dp[i][j]表示从 i 到 n 的人共接待 j 个人的花费(i 到 n这一段的花费)。dp[i][j]=min( dp[i+1][j] , dp[i+1][j-1] - a[i] + j*b[i] ),最后从大往小找dp[0][j]不超过K的最大的 j 即是答案。

    View Code
    #include <stdio.h>
    #include <algorithm>
    using namespace std;
    #define N 201
    struct node
    {
        int a,b;
        bool operator<(const node &t)    const
        {
            return b<t.b;
        }
    };
    node t[N];
    int n,m;
    int dp[N][N];
    void dfs(int i)
    {
        if(i==n)
        {
            dp[i][0]=t[n].a;
            dp[i][1]=t[n].b;
            return;
        }
        dfs(i+1);
        int j;
        dp[i][0]=dp[i+1][0]+t[i].a;
        for(j=1;j<=n-i;j++)
        {
            dp[i][j]=min(dp[i+1][j]+t[i].a,dp[i+1][j-1]+t[i].b*j);
        }
        dp[i][j]=dp[i+1][j-1]+t[i].b*j;
    }
    int main()
    {
        int ca=0;
        while(scanf("%d%d",&n,&m),(n|m))
        {
            for(int i=1;i<=n;i++)
            {
                scanf("%d%d",&t[i].a,&t[i].b);
            }
            sort(t+1,t+n+1);
            dfs(1);
            int cnt;
            for(cnt=n;cnt>=0 && dp[1][cnt]>m;cnt--);
            printf("%d: ",++ca);
            if(cnt<0) puts("Mission Impossible");
            else    printf("%d\n",cnt);
        }
        return 0;
    }
  • 相关阅读:
    坐标转换convertRect
    error this is not a media message!!!
    嵌入式-第一季-第4课
    嵌入式-第一季-第2课
    嵌入式-第一季-第3课
    嵌入式-第一季-第1课
    web-15. 事件与函数
    web-14. 表达式与程序流程
    web-13. 数组和字符串
    数据-第5课-线性表的本质
  • 原文地址:https://www.cnblogs.com/algorithms/p/2691018.html
Copyright © 2020-2023  润新知