题如其名啊,数据非常帅气
这题一眼就是dp题,而且状态的设计也比较简单
至于我考试的dp为什么不是满分
咳咳,绝对不是我状态设计得汤碗了
一看就是数据太废了,没有想到我的高级的点上
这能怪我吗???(bushi)
状态设计的有些抽象了
设dp[i][j]表示当前遍历到第i个垃圾,此时的高度为j,然后去存这个时候可以持续多长时间。
然后再看状态转移方程,有两种:
1.当上一步的持续时间大于现在的时间且当前的j可以保留垃圾时(高度之差大于等于零)
2.当上一步的持续时间大于现在的时间并将垃圾吃掉时
为什么这样写呢?
因为如果出去了,在 dp[i][n] 至 dp[i][2n] 里就会有数值,找j最小的数值
如果没有就在 dp[0][0] 至 dp[i][n-1] 找最大值
为什么是dp[0][0]?
因为你谷的数据十分毒瘤
#12#13的点,一个是吃不到一个垃圾,另一个是一个垃圾的高度直接就比井还高了
所以就可以上AC Code:
#include<bits/stdc++.h>
using namespace std;
inline int read_()
{
int x=0,f=1;
char c=getchar();
while(c<'0'||c>'9')
{
if(c=='-') f=-1;
c=getchar();
}
while(c>='0'&&c<='9') x=x*10+(c-48),c=getchar();
return x*f;
}
inline void out_(int x)
{
if(x<0) putchar('-'),x=-x;
if(x<10)
{
putchar(x+48);
return ;
}
out_(x/10),putchar(x%10+48);
return ;
}
int dp[105][2502];//因为是高度所以要多开一点空间
int i,j,k;
int n,m;
int maxn;
struct node{
int t;
int f;
int h;
};
node a[105];
bool cmp(node xx,node yy)
{
return xx.t<yy.t;
}
int main()
{
n=read_(),m=read_();
for(i=1;i<=m;++i) a[i].t=read_(),a[i].f=read_(),a[i].h=read_();
stable_sort(a+1,a+m+1,cmp);
dp[0][0]=10;
for(i=1;i<=2502;++i)
{
dp[0][1]=-1;
}
maxn=10;
for(i=1;i<=m;++i)
{
for(j=0;j<=max(50,2*n+2);++j)
{
if(j-a[i].h>=0&&a[i].t<=dp[i-1][j-a[i].h])//活着且可以堆
{
dp[i][j]=max(dp[i][j],dp[i-1][j-a[i].h]);
}
//不吃垃圾
if(dp[i-1][j]>=a[i].t)//还活着
dp[i][j]=max(dp[i][j],dp[i-1][j]+a[i].f);
//吃掉
}
}
for(i=1;i<=m;++i)
{
for(j=n;j<=max(50,2*n+2);++j)
{
if(dp[i][j]>=a[i].t)
{
out_(a[i].t);
return 0;
}
}
}
int ans;
for(i=0;i<=m;++i)
{
for(j=0;j<=2*n+50;++j)
{
ans=max(ans,dp[i][j]);//最大存活时间
}
}
out_(ans);
return 0;
}
下班!!!