版权声明:不念过去,不畏未来,一切都是过眼云烟。 https://blog.csdn.net/qq_34531807/article/details/83514695
题解:
用
表示横坐标为
时高度为j的最少点击次数。
用正无穷来表示不可能达到这个状态。
于是我们可以分析出状态转移的方式:
上升——完全背包转移方式
下降——
背包转移方式
超过
变为
——特判
#include<bits/stdc++.h>
#define ll long long
const int N=1e4+5;
using namespace std;
int n,m,k,vis[N],low[N],high[N],x[N],y[N],f[N][2005];
inline ll read()
{
ll x=0,f=1;char s=getchar();
while(s>'9'||s<'0'){if(s=='-')f=-1;s=getchar();}
while(s<='9'&&s>='0'){x=x*10+s-'0';s=getchar();}
return x*f;
}
int main()
{
n=read(),m=read(),k=read();
for(int i=1;i<=n;i++)
{
x[i]=read(),y[i]=read();
high[i]=m;low[i]=1;
}
for(int i=1;i<=k;i++)
{
int p=read(),l=read(),h=read();
vis[p]=1;low[p]=l+1;high[p]=h-1;
}
memset(f,0x3f,sizeof(f));
for(int i=1;i<=m;i++)f[0][i]=0;
for(int i=1;i<=n;i++)
{
for(int j=x[i]+1;j<=m+x[i];j++)
f[i][j]=min(f[i-1][j-x[i]]+1,f[i][j-x[i]]+1);
for(int j=m+1;j<=m+x[i];j++)f[i][m]=min(f[i][m],f[i][j]);
for(int j=1;j<=m-y[i];j++)f[i][j]=min(f[i][j],f[i-1][j+y[i]]);
for(int j=1;j<low[i];j++)f[i][j]=f[0][0];
for(int j=high[i]+1;j<=m;++j)f[i][j]=f[0][0];
}
int ans=f[0][0];
for(int j=1;j<=m;j++)ans=min(ans,f[n][j]);
if(ans<f[0][0])printf("1\n%d\n",ans);else
{
int i,j;
for(i=n;i>=1;i--)
{
for(j=1;j<=m;j++)
if(f[i][j]<f[0][0])break;
if(j<=m)break;
}
ans=0;
for(int j=1;j<=i;j++)if(vis[j])ans++;
printf("0\n%d\n",ans);
}
return 0;
}