zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    Leetcode Plus One
    Leetcode Swap Nodes in Pairs
    Leetcode Remove Nth Node From End of List
    leetcode Remove Duplicates from Sorted Array
    leetcode Remove Element
    leetcode Container With Most Water
    leetcode String to Integer (atoi)
    leetcode Palindrome Number
    leetcode Roman to Integer
    leetcode ZigZag Conversion
  • 原文地址:https://www.cnblogs.com/algorithms/p/2691018.html
Copyright © 2011-2022 走看看