Boat - UVaLive 2511 价值改变的01背包

You are the owner of a very nice boat. You have many requests to rent your beautiful boat during the summer time and you decided to maximize your profit. For each client you know the number of days he wants to rent the boat and a list of choices, where a choice means an amount of money and a deadline. The deadline is the number of days counted from a time origin. You get the money for a given deadline (when the holiday must end) only if you are able to rent the boat before that deadline. For example your friend Jack wants to travel on the Mediterranean Sea for 20 days and has the following choices:

  • if the holiday deadline is 60 days you can get 1000 EUR provided the boat is rented in between 0 and 41 (60days-20days+1) for 20 days;
  • if the holiday deadline is 70 days you can get 800 EUR.
If a client does not contribute to the maximization of your profit you can drop that client. You know all the clients and their choices and you must rent the boat according to the order in which the clients submit their requests. Write a program that, given the clients, computes the largest profit you can get.

Input 

The program input is from a text file. Each data set in the input has the following format:
  • n - the number of clients (n$ \le$100)
  • on n separate lines the number of days (at most 100) each client wishes to rent the boat;
  • the total number of choices for all clients;
  • the list of choices in the format client$ \_id$deadlineamount$ \_of$$ \_money$ where the client$ \_id$ is a positive integer in the range 1...n and deadline$ \le$100.
An empty line separates the input data sets.

Output 

For each data set the program must print (from the beginning of a line) the maximum profit for that set. The results must be printed on the standard output. An empty line separates the results of different data sets.

Sample Input 

3
2
2
4
4
1 2 14
3 4 25
2 4 12
3 3 10

Sample Output 

26

题意:每个人有对于船的需求天数,然后在他规定的天数范围内借给他时会有相应的报酬,每个人只需要借一次船,问你最后的最大收益是多少。

思路:这是一道价值改变的01背包,dp[i]表示在前i天借船的最大收益,num[i][j]表示第i个人在第j天借给他时的收益,dp[j]=max(dp[j],dp[j-day[i]]+num[i][j])。

AC代码如下:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int dp[110];
int num[110][110],day[110];
int main()
{
    int t=0,n,m,i,j,k,a,b,c,ans;
    while(~scanf("%d",&n))
    {
        for(i=1;i<=n;i++)
           scanf("%d",&day[i]);
        scanf("%d",&m);
        memset(dp,0,sizeof(dp));
        memset(num,0,sizeof(num));
        while(m--)
        {
            scanf("%d%d%d",&a,&b,&c);
            for(j=b;j>=0;j--)
               num[a][j]=max(num[a][j],c);
        }
        for(i=1;i<=n;i++)
           for(j=100;j>=day[i];j--)
              dp[j]=max(dp[j],dp[j-day[i]]+num[i][j]);
        ans=0;
        for(i=0;i<=100;i++)
           ans=max(ans,dp[i]);
        if(t!=0)
          printf("\n");
        t++;
        printf("%d\n",ans);
    }
}



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值