ACM: 动态规划题 poj 1036 问题简…

Gangsters

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

 

题意: 现在有N个歹徒, 要获取旅馆里面的财物, 但是旅馆有一扇可以改变大小的门,

      门一开始处于关闭, 并且范围是[0,K]之间变化, 现在有每个歹徒到达时间为Ti;

      并且有一个规则, 门可以每秒+1,-1,保持不变三种状态.并且歹徒在相应Ti时间

      到达旅馆时,门的大小与他的Si值一样时,则可以进去获取相应Pi财物值.否则不进去.

 

解题思路:

       1. 先将每个歹徒按照到达时间从小到大排序.为后面设状态做铺垫.后面描述基于排序好序列.

       2. 根据排好序, 设状态: dp[i]表示前i个歹徒到达旅馆可以获取最大的∑Pi.

       3. 状态转移方程: dp[i] = dp[j]+p[i];

          问题分析:

            (1).上述方程必须要满足条件才行.要想从某个前j个歹徒的状态中转移到前i个歹徒.

                显然满足: dp[i] <= dp[j];

            (2).要想从dp[j]转移到dp[i], 还必须满足可以到达的条件. 即: 当门的大小恰好等于

                s[j]时, 通过了T[i]-T[j]时间之后要大于等于|s[i]-s[j]|; (因为门每秒有三个状态)

                即: T[i]-T[j] >= |s[i]-s[j]|;

        4.最后我想说明一点这样分析此问题的正确性.

          dp[i] = dp[j]+p[i];转移方程恰好满足动态规划问题的"剪贴"思想.

          并且重要的一点是dp[i]每个状态包含一条隐性的路径.就是前i个歹徒中选取了哪几个.

          并且每个子问题相互独立.

代码:

#include <cstdio>

#include <iostream>

#include <cstring>

#include <cstdlib>

using namespace std;

#define MAX 105

 

struct node

{

 int p, s, t;

}a[MAX];

 

int N, K, T;

int dp[MAX];

 

int cmp(const void *a, const void *b)

{

 return ((node*)a)->t - ((node*)b)->t;

}


inline int my_abs(int a)
{
 return a > 0 ? a : (-a);
}

 

int main()

{

// freopen("input.txt","r",stdin);

 while(scanf("%d %d %d",&N,&K,&T) != EOF)

 {

  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);
  qsort(a+1,N,sizeof(a[0]),cmp);

  memset(dp,0,sizeof(dp));
  int result = 0;
  for(int i = 1; i <= N; ++i)
  {
   if(a[i].t > T) break;
   if(a[i].s > a[i].t) continue;
   for(int j = 1; j < i; ++j)
   {
    if(dp[j] >= dp[i] && my_abs(a[i].t-a[j].t) >= my_abs(a[i].s-a[j].s) )
     dp[i] = dp[j];
   }
   if(dp[i] >= 0) dp[i] += a[i].p;

   if(result < dp[i])
    result = dp[i];
  }
  printf("%d\n",result);

 }
 return 0;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值