描述
There are n events in the parade. Each one can be performed for at most k times.
The parade will last for m minutes. The major will give a talk at the end, so you should make at least one minute idle.
Each events have three attributions, ai, bi, ci. If the parade have p minutes remaining when the i-th event begins, the excitement of the parade will increase by ai-(m-p)*bi and the event will last for ci minutes.
You should arrange the events to maximize excitement and guarantee at least one minute at the end will be free.
输入
Three integers n, m ,k on the first line.
The following n lines, there are three integers ai, bi, ci, denoting the attributions of the events.
0 <= ai, bi, ci <= 10000
For 20% of the data, n<=5, m<=10, k<=5;
For 60% of the data, n<=200, m<=500, k<=50;
For 100% of the data, n<=1000, m<=5000, k<=1000
输出
One integer on one line, denoting the answer.
TLE代码:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int dp[1000][500];
struct Event{
int a, b, c;
double d;
}event[1001];
int calc(int s, int e, int i){
int j = (e-s)/event[i].c;
return event[i].a*j - event[i].b*(j*s + event[i].c*(j-1)*j/2);
}
int cmp(const void* a, const void* b){
return ((struct Event*)a)->d < ((struct Event*)b)->d ? 1:-1;
}
int main(){
int n, m, k, i, tempvalue, max, v, j;
scanf("%d%d%d", &n, &m, &k);
for(i = 1; i <= n; i++){
scanf("%d%d%d", &event[i].a, &event[i].b, &event[i].c);
event[i].d = (double)event[i].b/(double)event[i].c;
}
qsort(&event[1], n, sizeof(struct Event), cmp);
memset(dp, 0, sizeof(dp));
for(i = 1; i <= n; i++){
for(v = 0; v < m; v++){
for(j = 0; j <= k && j*event[i].c <= v; j++){
tempvalue = calc(v-event[i].c*j, v, i);
if(dp[i][v] < dp[i-1][v-event[i].c*j] + tempvalue)
dp[i][v] = dp[i-1][v-event[i].c*j] + tempvalue;
}
}
}
for(max = dp[n][0], i = 1; i < m; i++){
if(max < dp[n][i])
max = dp[n][i];
}
printf("%d\n", max);
return 0;
}
AC代码:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int dp[1001][5000], q[10000][500];
struct Event{
int a, b, c;
double d;
}event[1001];
int calc(int s, int e, int i){
int j = (e-s)/event[i].c;
return event[i].a*j - event[i].b*(j*s + event[i].c*(j-1)*j/2);
}
int cmp(const void* a, const void* b){
return ((struct Event*)a)->d < ((struct Event*)b)->d ? 1:-1;
}
int main(){
int n, m, k, i, tempvalue, max, v, j, tail[10000], head[10000], r;
int tempvalue1, tempvalue2, value1, value2;
scanf("%d%d%d", &n, &m, &k);
for(i = 1; i <= n; i++){
scanf("%d%d%d", &event[i].a, &event[i].b, &event[i].c);
event[i].d = (double)event[i].b/(double)event[i].c;
}
qsort(&event[1], n, sizeof(struct Event), cmp);
memset(dp, 0, sizeof(dp));
for(i = 1; i <= n; i++){
memset(tail, 0, sizeof(tail));
for(j = 0; j < event[i].c; j++){
head[j] = 1;
}
for(v = 0; v < m; v++){
r = v%event[i].c;
tail[r]++;
q[r][tail[r]] = v;
while(tail[r] > head[r]){
tempvalue1 = calc(q[r][tail[r]], v, i);
value1 = dp[i-1][q[r][tail[r]]] + tempvalue1;
tempvalue2 = calc(q[r][tail[r]-1], v, i);
value2 = dp[i-1][q[r][tail[r]-1]] + tempvalue2;
if(value1 >= value2){
q[r][tail[r]-1] = q[r][tail[r]];
tail[r]--;
}else{
break;
}
}
while((v - q[r][head[r]])/event[i].c > k){
head[r]++;
}
tempvalue = calc(q[r][head[r]], v, i);
dp[i][v] = dp[i-1][q[r][head[r]]] + tempvalue;
}
}
for(max = dp[n][0], i = 1; i < m; i++){
if(max < dp[n][i])
max = dp[n][i];
}
printf("%d\n", max);
return 0;
}
为何要排序?
因为枚举时每加入一个新的event,总是把它放在最后