/*
http://poj.org/problem?id=1036 Gangsters
翻譯: N 個盜賊去一個飯店,第i個盜賊在Ti時間來,他擁有Pi的財富。這個飯店的門有
K+1種開放的狀態,用[0,K]表示。這些狀態能夠被一個盜賊改變在一個時間單位內,要麼把
它打開,要麼把它關閉,或者就是維持原狀。在初始時刻這些門都是關閉着的。第i個盜賊
進入了飯店僅當這個門是專門爲他所開放的時候,也就是說這個門的狀態與他的堅強程度Si
一致的時候。當盜賊來到飯店的這一刻,如果開放的狀態不等於盜賊的堅強程度的時候,這
個盜賊就不會再來了。
飯店的工作時間爲區間[0,T]
目標是幫 盜賊在飯店裏收集到最大的財富,通過恰當的打開或者關閉門。
思路:按照時間將盜賊排序,排在前面的盜賊先進飯店,我們知道如果時間一旦進過了某給點,那麼那個時候的盜賊所能產生的價值已經固定了,後來的不會對他的價值有影響了,因此我們只需要循環枚舉一下這些盜賊的組合即可算出最大價值。
4 10 20
10 16 8 16
10 11 15 1
10 7 1 8
3 100 100
3 5 6
11 11 11
15 32 51
*/
#include <map>
#include <cmath>
#include <vector>
#include <string>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define CLR(c,v) (memset(c,v,sizeof(c)))
using namespace std;
struct G{
int t,v,c;
bool operator <(const G &a)const {
return t < a.t;
}
}g[200];
int main(){
freopen("in.txt","r",stdin);
int n , k, t;
while(cin >> n >> k >> t){
CLR(g,0);
for(int i = 0 ; i < n ; i++)
scanf("%d",&g[i].t);
for(int i = 0 ; i < n ; i++)
scanf("%d",&g[i].v);
for(int i = 0 ; i < n ; i++)
scanf("%d",&g[i].c);
sort(g , g + n);
int ans = 0;
for(int i = 0 ; i < n ; i ++){
int mmax = 0;
for(int j = 0 ; j < i ; j++){
if(abs(g[j].c - g[i].c) <= g[i].t - g[j].t){
mmax = max(g[j].v , mmax);
}
}
g[i].v = ( g[i].c > g[i].t ? 0 : mmax + g[i].v); // 把每
個賊的價值更新爲最大值,如果能達到
ans = max(ans , g[i].v);
}
cout << ans << endl;
}
return 0;
}
POJ 1036 Gangsters -- 常規dp 題意好難懂啊
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.