题意:
N 个盗贼去一个饭店,第i个盗贼在Ti时间来,他拥有Pi的财富。这个饭店的门有K+1种开放的状态,用[0,K]表示。这些状态能够被一个盗贼改变在一个时间单位内,要么把它打开,要么把它关闭,或者就是维持原状。在初始时刻这些门都是关闭着的。第i个盗贼进入了饭店仅当这个门是专门为他所开放的时候,也就是说这个门的状态与他的坚强程度Si一致的时候。当盗贼来到饭店的这一刻,如果开放的状态不等于盗贼的坚强程度的时候,这个盗贼就不会再来了。饭店的工作时间为区间[0,T]目标是帮 盗贼在饭店里收集到最大的财富,通过恰当的打开或者关闭门。
典型到DP问题,根据时间将到餐馆到人排序,当第i个人来餐馆时可获得最大财富dp[i]取决于前面i-1个人结果,需要在前面i-1个人里找在时间差内门开放状态可以变成i到size时到最大值。语言不好描述,直接看代码吧
import java.io.*;
import java.util.Arrays;
public class Main {
static int maxn = 101;
static int N, K, T, ans;
static Node[] nodes = new Node[maxn];
static int dp[] = new int[maxn];
static StreamTokenizer st;
public static void main(String[] args) throws Exception {
// 初始化
// System.setIn(new FileInputStream(new File("resources/Solution_poj1036.txt")));
st = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
N = nextToken();
K = nextToken();
T = nextToken();
ans = 0;
for (int i = 0; i < N; i++) {
nodes[i] = new Node();
}
Arrays.fill(dp, 0, N,0);
for (int i = 0; i < N; i++) {
nodes[i].time = nextToken();
}
for (int i = 0; i < N; i++) {
nodes[i].prise = nextToken();
}
for (int i = 0; i < N; i++) {
nodes[i].size = nextToken();
}
Arrays.sort(nodes, 0, N);
//
for (int i = 0; i < N; i++) {
if (nodes[i].time < nodes[i].size)
continue;
for (int j = 0; j < i; j++) {
if (nodes[i].time - nodes[j].time >= absReduce(nodes[i].size, nodes[j].size))
dp[i] = max(dp[i], dp[j]);
}
dp[i] += nodes[i].prise;
ans = max(ans, dp[i]);
}
System.out.println(ans);
}
private static int max(int a, int b) {
return a>b ? a : b;
}
private static int absReduce(int a, int b) {
return a>b ? a-b : b-a;
}
private static int nextToken() throws IOException {
st.nextToken();
return (int) st.nval;
}
static class Node implements Comparable<Node> {
int time;
int prise;
int size;
@Override
public int compareTo(Node o) {
return this.time - o.time;
}
}
}