Tar 把一段凹凸不平的路分成了高度不同的 N 段(每一段相同高度),并用 H[i] 表示第 i 段高度。现在 Tar 一共有 n 种泥土可用,它们都能覆盖给定的连续的 k 个部分。
对于第 i 种泥土,它的价格为 C[i],可以使得区间 [i,min(n,i+k-1)] 的路段的高度增加 E[i]。
Tar 要设定一种泥土使用计划,使得使用若干泥土后,这条路最低的高度尽量高,并且这个计划必须满足以下两点要求:
(1)每种泥土只能使用一次。
(2)泥土使用成本必须小于等于 M 。
请求出这个最低的高度最高是多少。
第一行为如上文所示的三个正整数:N,M,K。
接下来 N 行,每行3个如上文所示的正整数 H[i],E[i],C[i]。
【数据范围】
对于 30% 的数据:N≤20。
对于 100% 的数据:1≤K≤11;1≤N≤100;0≤M,H[i],E[i],C[i]≤1000000。
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<ctime>
#include<cctype>
#include<cstring>
#include<string>
#include<algorithm>
using namespace std;
const int N=105;
const int inf=1e+9;
int n,m,k;
int h[N],e[N],c[N];
int bit[15];
int dp[N][5000],g[5000];
bool jud[N];
inline int R()
{
int f=0;
char c;
for(c=getchar();(c<‘0‘||c>‘9‘);c=getchar());
for(;c<=‘9‘&&c>=‘0‘;c=getchar())
f=(f<<3)+(f<<1)+c-‘0‘;
return f;
}
inline int find(int x)
{
for(int i=k-1;i>=0;i--)
if(x>=bit[i]) return i;
}
inline bool work(int minn)
{
memset(dp,-1,sizeof(dp));
dp[0][0]=0;
memset(jud,false,sizeof(jud));
jud[0]=true;
for(int i=1;i<=n;i++)
{
if(!jud[i-1])
return false;
g[0]=0;
int maxx=(i<k?bit[i]:bit[k]);
for(int j=0;j<maxx;j++)
{
int temp;
if(j==0) g[j]=0;
else
{
temp=find(j);
g[j]=g[j-bit[temp]]+e[i-temp];
}
if(g[j]+h[i]<minn) continue;
if(dp[i-1][j>>1]==-1&&dp[i-1][(j>>1)+bit[k-1]]==-1) continue;
if(dp[i-1][j>>1]==-1)
temp=dp[i-1][(j>>1)+bit[k-1]];
else
{
if(dp[i-1][(j>>1)+bit[k-1]]==-1)
temp=dp[i-1][j>>1];
else
temp=min(dp[i-1][j>>1],dp[i-1][(j>>1)+bit[k-1]]);
}
dp[i][j]=temp+(j&1)*c[i];
if(dp[i][j]>m) dp[i][j]=-1;
else jud[i]=true;
}
}
return jud[n];
}
int main()
{
// freopen("a.in","r",stdin);
n=R(),m=R(),k=R();
for(int i=1;i<=n;i++)
h[i]=R(),e[i]=R(),c[i]=R();
bit[0]=1;
for(int i=1;i<=k;i++)
bit[i]=bit[i-1]*2;
int left=inf,right;
for(int i=1;i<=n;i++)
left=min(left,h[i]);
right=h[1]+e[1];
for(int i=1;i<=n;i++)
{
int temp=h[i];
for(int j=i;j>=i-k+1&&j>=1;j--)
temp+=e[j];
right=max(temp,right);
}
int ans=left;
while(left<=right)
{
int mid=(left+right)/2;
if(work(mid)) ans=mid,left=mid+1;
else right=mid-1;
}
cout<<ans<<endl;
return 0;
}