Description
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 second line of the input file contains the moments of time when gangsters come to the restaurant T1, T2, ..., TN, separated by spaces. ( 0 <= Ti <= T for i = 1, 2, ..., N)
?The third line of the input file contains the values of the prosperity 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 the stoutness 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
Sample Input
4 10 20 10 16 8 16 10 11 15 1 10 7 1 8
果然dp很难,一般做法是,设dp[i][j]表示时间在0-i,门的状态为j时的最优解,那么
dp[i][j]=max(dp[i-1][j-1],dp[i-1][j],dp[i-1][j+1])
想要求最优解,那么当然从第i时间可能能进入的情况入手,那么上一个时间的门的状态显然只有3个,由于第i时间的最优解只和第i-1时间有关,本题内存也有限制,所以要采用滚动数组,下面是代码
遗憾的是,按上面的写法,我还是超内存了,也许可以在此基础上优化,但是,从递推式本身出发,可以大大解决内存的问题。按第i个人来考虑,如果第i个人可以进入,那么就先把dp[i]赋值为value[i],显然第i个人的状态一定要继承到前i个人中最优的那个人(当然那个人也要可以进入那扇门)
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<map>
#include<iostream>
#include<set>
#include<vector>
using namespace std;
int dp[2][105];
struct node
{
int p,s,t;
}people[105];
int _hash[30010][100];
int main()
{
int n,k,t;
while(~scanf("%d%d%d",&n,&k,&t))
{
memset(_hash,0,sizeof(_hash));
memset(dp,0,sizeof(dp));
for(int i=1;i<=n;i++)
scanf("%d",&people[i].t);
for(int i=1;i<=n;i++)
scanf("%d",&people[i].p);
for(int i=1;i<=n;i++)
scanf("%d",&people[i].s);
for(int i=1;i<=n;i++)
if(people[i].s <= people[i].t)
_hash[ people[i].t][people[i].s + 1]+=people[i].p;//我们把可以进入的人全部保存在hash数组里,计算出每个时间点可以进入的人的价值总和
for(int i=1;i<=t;i++)
for(int j=1;j<=k+1 && j<=i+1;j++)
dp[i&1][j]=max(dp[(i-1)&1][j-1],max(dp[(i-1)&1][j],dp[(i-1)&1][j+1]))+_hash[i][j];
int ans=0;
for(int i=1;i<=k+1;i++)
ans=max(ans,dp[t&1][i]);
printf("%d\n",ans);
}
return 0;
}
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<iostream>
using namespace std;
int dp[110];
struct node
{
int p,s,t;
}gaster[105];
int _ok[105];
int cmp(node a,node b)
{
return a.t < b.t;
}
int main()
{
int n,t,k;
while(~scanf("%d%d%d",&n,&k,&t))
{
memset(dp,0,sizeof(dp));
for(int i=0;i<n;i++)
scanf("%d",&gaster[i].t);
for(int i=0;i<n;i++)
scanf("%d",&gaster[i].p);
for(int i=0;i<n;i++)
scanf("%d",&gaster[i].s);
sort(gaster,gaster+n,cmp);
for(int i=0;i<n;i++)
if(gaster[i].s <= gaster[i].t)
_ok[i]=gaster[i].p;
else
_ok[i]=0;
for(int i=0;i<n;i++)
{
if(_ok[i]!=0)
dp[i]=_ok[i];
else
dp[i]=0;
for(int j=0;j<i;j++)
if(dp[j] && fabs(gaster[i].s - gaster[j].s) <= fabs(gaster[i].t - gaster[j].t ))//设//一段时间内门的变化值为Δt,那么当且仅当s的变化值Δs <=Δt才满足第i个人可以进入门的条件
dp[i]=max(dp[i],dp[j]+_ok[i]);
}
int ans=0;
for(int i=0;i<n;i++)
ans=max(ans,dp[i]);
printf("%d\n",ans);
}
return 0;
}