题目链接
这题关于DP
用f[i][j]表示横坐标为i时高度为j的最少点击次数。
用正无穷来表示不可能达到这个状态。
于是我们可以分析出状态转移的方式:
上升——完全背包转移方式
下降——01背包转移方式
超过m变为m——特判
细节详见代码
#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;
int maxx=100000;
int l[10010],h[10010];
int f[10010][1010];
int x[10010],y[10010];
bool p[10010];
int main()
{
int n,i,j,k,m,w;
cin>>n>>m>>k;
for(i=0;i<n;i++)
{
cin>>x[i]>>y[i];
l[i]=0;
h[i]=m+1;
}
l[n]=0;
h[n]=m+1;
for(i=0;i<k;i++)
{
cin>>w;
cin>>l[w]>>h[w];
p[w]=true;
}
for(i=1;i<=n;i++)
{
for(j=0;j<=m;j++)
{
f[i][j]=maxx;
}
}
f[0][0]=maxx;
for(i=1;i<=m;i++)
{
f[0][i]=0;
}
for(i=1;i<=n;i++)
{
for(j=x[i-1];j<=m;j++)
{
if(j==m)
{
for(w=m-x[i-1];w<=m;w++)
{
f[i][j]=min(f[i][j],f[i-1][w]+1);
f[i][j]=min(f[i][j],f[i][w]+1);
}
}
f[i][j]=min(f[i][j],f[i-1][j-x[i-1]]+1);
f[i][j]=min(f[i][j],f[i][j-x[i-1]]+1);
}
for(j=max(1,l[i]+1);j<=min(m-y[i-1],h[i]-1);j++)
{
f[i][j]=min(f[i][j],f[i-1][j+y[i-1]]);
}
for(j=l[i];j>=1;j--)
{
f[i][j]=maxx;
}
for(j=h[i];j<=m;j++)
{
f[i][j]=maxx;
}
}
int ans=maxx;
int cnt=k;
for(i=n;i>=1;i--)
{
for(j=l[i]+1;j<=h[i]-1;j++)
{
ans=min(ans,f[i][j]);
}
if(ans<maxx)
{
break;
}
if(p[i]==true)
{
k--;
}
}
if(cnt==k)
{
cout<<"1"<<endl<<ans;
}
else
{
cout<<"0"<<endl<<k;
}
return 0;
}