POJ 1036 Gangsters(DP)

Gangsters
Time Limit: 1000MS Memory Limit: 10000K
Total Submissions: 12559 Accepted: 3556

Description

N gangsters are going to a restaurant. The i-th gangster comes at the time Ti and has the prosperity Pi. The door of the restaurant has K+1 states of openness expressed by the integers in the range [0, K]. The state of openness can change by one in one unit of time; i.e. it either opens by one, closes by one or remains the same. At the initial moment of time the door is closed (state 0). The i-th gangster enters the restaurant only if the door is opened specially for him, i.e. when the state of openness coincides with his stoutness Si. If at the moment of time when the gangster comes to the restaurant the state of openness is not equal to his stoutness, then the gangster goes away and never returns. 
The restaurant works in the interval of time [0, T]. 
The goal is to gather the gangsters with the maximal total prosperity in the restaurant by opening and closing the door appropriately. 

Input

?The first line of the input file contains the values N, K, and T, separated by spaces. (1 <= N <= 100 ,1 <= K <= 100 ,0 <= T <= 30000 ) 
?The second line of the input file contains the moments of time when gangsters come to the restaurant T1, T2, ..., TN, separated by spaces. ( 0 <= Ti <= T for i = 1, 2, ..., N) 
?The third line of the input file contains the values of the prosperity of gangsters P1, P2, ..., PN, separated by spaces. ( 0 <= Pi <= 300 for i = 1, 2, ..., N) 
?The forth line of the input file contains the values of the stoutness of gangsters S1, S2, ..., SN, separated by spaces. ( 1 <= Si <= K for i = 1, 2, ..., N) 
All values in the input file are integers. 

Output

Print to the output file the single integer ?the maximal sum of prosperity of gangsters in the restaurant. In case when no gangster can enter the restaurant the output should be 0.

Sample Input

4 10 20
10 16 8 16
10 11 15 1
10 7 1 8

Sample Output

26

Source

Northeastern Europe 1998


     题意:因为翻译过来很奇怪,所以我稍微修改了一下意思。N个人去餐厅吃饭,门的开放状态从0到K,刚开始门的开放状态为0,并且每一时刻门有3种调整状态,1,开放状态不变,2,开放状态-1 3,开放状态+1。 这N个人有一个体型宽度Si,只有当顾客在Ti这时刻来临时 ,门的开放状态等于Si 时顾客才会进去,如果不一样顾客就会永不回来。现在告诉你在0~T的时间段内这N个顾客的体型宽度Si和来的时间Ti以及店家获得的利润Pi,问你会获得的利润最大多少?


  这道题理解很难,但是理解之后题就很简单了,就是一个类似于背包的DP,只不过多了一个时间的条件。

首先是状态dp[i][j],表示在i时刻开放程度为j时的最大利润。

其次转移方程:dp[i][j]=max(dp[i-1][j-1],dp[i-1][j],dp[i-1][j+1]),

不过有一点和背包不同的是,在Ti时刻,考虑是否让顾客进来,其他时间是没有顾客的,所以对顾客进入时间进行排序,依次判断就行了。


#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#define inf 0x6fffffff
#define mem(p,k) memset(p,k,sizeof(p));
using namespace std;
struct SD{
    int p,s,t;
}a[110];
int dp[110],pre[110];//因为内存限制,所以用滚动数组
bool cmp(struct SD a,struct SD b){
    //if(a.t==b.t)return  a.s<b.s;
    return a.t<b.t;
}
int main(){
    int n,k,t;
    while(cin>>n>>k>>t){
        for(int i=1;i<=n;i++)scanf("%d",&a[i].t);
        for(int i=1;i<=n;i++)scanf("%d",&a[i].p);
        for(int i=1;i<=n;i++)scanf("%d",&a[i].s);
        sort(a+1,a+n+1,cmp);
        mem(dp,0);
        mem(pre,0);
        int maxx,cur=1;
        while(a[cur].t==0)cur++;//把0时刻进入的顾客删去,
        for(int i=1;i<=t;i++){
          for(int j=0;j<=min(i,k);j++){
            int m=pre[j];
            if(j-1>=0)m=max(m,pre[j-1]);
            if(j+1<=min(k,i)){
                m=max(m,pre[j+1]);
            }
            dp[j]=m;
          }

          while(a[cur].t==i&&cur<=n){//当i时有顾客进去时,直接加入对应Si的位置中
            if(a[cur].s>a[cur].t);
            else dp[a[cur].s]+=a[cur].p;
            cur++;
          }
          for(int j=0;j<=min(i,k);j++)pre[j]=dp[j];
        }
        maxx=0;
        for(int i=0;i<=k;i++)maxx=max(maxx,dp[i]);
        cout<<maxx<<endl;
    }

}



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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值