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

来源:互联网 发布:mac安装jdk 编辑:程序博客网 时间:2024/06/05 11:37
Gangsters

Description

N gangsters are going to arestaurant. The i-th gangster comes at the time Ti and has theprosperity Pi. The door of the restaurant has K+1 states ofopenness expressed by the integers in the range [0, K]. The stateof openness can change by one in one unit of time; i.e. it eitheropens by one, closes by one or remains the same. At the initialmoment of time the door is closed (state 0). The i-th gangsterenters the restaurant only if the door is opened specially for him,i.e. when the state of openness coincides with his stoutness Si. Ifat the moment of time when the gangster comes to the restaurant thestate of openness is not equal to his stoutness, then the gangstergoes away and never returns.
The restaurant works in the interval of time [0, T].
The goal is to gather the gangsters with the maximal totalprosperity in the restaurant by opening and closing the doorappropriately.

Input

?The first line of the inputfile 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 timewhen gangsters come to the restaurant T1, T2, ..., TN, separated byspaces. ( 0 <= Ti <= T for i = 1, 2,..., N)
?The third line of the input file contains the values of theprosperity 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 thestoutness 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 thesingle integer ?the maximal sum of prosperity of gangsters in therestaurant. In case when no gangster can enter the restaurant theoutput 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;

}

0 0