Codeforces Gym 100819S Surf
传送门
题意:一个人去冲浪,给了每个浪来的时间,以及冲这个浪带来的欢乐值和冲这个浪花费的时间。求最大欢乐值。(保证同一时间不会出现重复的浪)
比如有4个浪
4
8 50 2
10 40 2
2 80 9
13 20 5
第一个浪在第2分钟,冲它可以得到80的快感,冲完后时间变成了2+9=11,此时时间为8,10的浪就无法冲了,只能冲时间为13的浪,那么他的快感总值就为100。如果选择放弃第2分钟的那个浪,那么从第8分钟开始,他可以冲第8,10,13分钟的浪,总值为110。所以可以获得最大欢乐值为110。
思路:一看就知道是dp,刚开始以每个浪为变量,怎么都推不出转移方程,后来问了问,说是以每个时间为变量,即dp[i]表示第i分钟能获得的最大值。写了个转移方程
dp[i]=max{dp[i-1],dp[i+w[i]]+f[i]}
w[i]表示等待的时间,f[i]表示能获得的快感。
因为dp[i+w[i]]不知道
只能倒着推
即
dp[i]=max{dp[i+1],dp[i+w[i]]+f[i]}
因为数据保证在1000000以内,所以1000001的快感为0。
代码如下
#include<stdio.h>
#define max(a,b) (a>b?a:b)
inline int read()
{
int x=0;
char ch=getchar();
while(ch>='0'&&ch<='9')
x=x*10+ch-48,ch=getchar();
return x;
}
int n,f[1000005],w[1000005];
long long dp[1000005];
int main()
{
n=read();
for(int i=1;i<=n;i++)
{
int s;
s=read();
f[s]=read();
w[s]=read();
}
for(int i=1000000;i>0;i--)
{
if(f[i])
{
if(i+w[i]>1000000)
dp[i]=max(dp[i+1],f[i]);
else
dp[i]=max(dp[i+1],f[i]+dp[i+w[i]]);
}
else dp[i]=dp[i+1];
}
printf("%I64d",dp[1]);
return 0;
}
加了一个输入外挂,时间优化快了一倍,233…..