天天看點

UVA 672 - Gangsters(dp)   Gangsters 

  Gangsters 

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 stoutnessSi. 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 is an integer M, then a blank line followed by M datasets. There is a blank line between datasets.

The first line of each dataset contains the values N, K, and T, separated by spaces. (

UVA 672 - Gangsters(dp)   Gangsters 

)

The second line of the dataset contains the moments of time when gangsters come to the restaurant

UVA 672 - Gangsters(dp)   Gangsters 

, separated by spaces. ( 

UVA 672 - Gangsters(dp)   Gangsters 

 for 

UVA 672 - Gangsters(dp)   Gangsters 

)

The third line of the dataset contains the values of the prosperity of gangsters 

UVA 672 - Gangsters(dp)   Gangsters 

, separated by spaces. ( 

UVA 672 - Gangsters(dp)   Gangsters 

 for 

UVA 672 - Gangsters(dp)   Gangsters 

)

The forth line of the dataset contains the values of the stoutness of gangsters 

UVA 672 - Gangsters(dp)   Gangsters 

, separated by spaces. ( 

UVA 672 - Gangsters(dp)   Gangsters 

 for 

UVA 672 - Gangsters(dp)   Gangsters 

)

All values in the input file are integers.

Output 

For each dataset, print 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. Print a blank line between datasets.

Sample Input 

1

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

Sample Output 

26      

題意:

有個酒店的門會改變尺寸,變化範圍是【0,k】,這個門每秒鐘尺寸可以變大1,可以減小1,也可以不變。

現在有n個人,他們的尺寸為si,每個人在ti時刻想要進入酒店,隻有在ti時刻酒店門的尺寸恰好和這個人的尺寸大小相等,這個人才可以進入。

每個人有一個值Pi,當某人進入酒店,酒店就會增加Pi值。

在[0,T]這段時間内(0秒時酒店的門尺寸狀态是0),求讓一些人進入酒店,使得總Pi值最大。

思路:dp,定義dp[i]表示第i個人可以進入的情況的最大p值,狀态轉移方程為(if dp[j]狀态存在并且dp[j]能到dp[i]狀态) dp[i] = dp[j] + p[i];

代碼:

#include <stdio.h>
#include <string.h>
#include <math.h>
#include <algorithm>
#define max(a,b) ((a)>(b)?(a):(b))
using namespace std;

const int N = 105;
int T, n, k, t, i, j, dp[N];
struct Man {
	int t, p, s;
} m[N];

bool cmp(Man a, Man b) {
	return a.t < b.t;
}

int solve() {
	int ans = 0;
	sort(m + 1, m + n + 1, cmp);
	memset(dp, -1, sizeof(dp));
	dp[0] = 0;
	for (i = 1; i <= n; i++) {
		for (j = 0; j < i; j++) {
			int Time = m[i].t - m[j].t;
			int s = abs(m[i].s - m[j].s);
			if (s > Time || dp[j] == -1) continue;
			dp[i] = max(dp[i], dp[j] + m[i].p);
			
		}
		ans = max(ans, dp[i]);
	}
	return ans;
}

int main() {
	scanf("%d", &T);
	while (T--) {
		scanf("%d%d%d", &n, &k, &t);
		for (i = 1; i <= n; i++)
			scanf("%d", &m[i].t);
		for (i = 1; i <= n; i++)
			scanf("%d", &m[i].p);
		for (i = 1; i <= n; i++)
			scanf("%d", &m[i].s);
		printf("%d\n", solve());
		if (T) printf("\n");
	}
	return 0;
}
           

繼續閱讀