您的位置:首页 > 其它

洛谷P1941 飞扬的小鸟

2017-08-24 17:09 253 查看
NOIP14的题,比较水的DP,向上弹的时候做一个完全背包,向下因为只能掉一次做一个01背包。
#include <bits/stdc++.h>
using namespace std;
#define maxn 10005
#define maxn2 1005
#define INF 1<<25
int low[maxn],high[maxn];
int x[maxn],y[maxn];
int n,m,k;
int p[maxn];
void read(int &x)
{
int f=1,ans=0;
char c;
c=getchar();
while (c!='-' && (c<'0' || c>'9'))
{
c=getchar();
}
while (c=='-') {f*=-1;c=getchar();}
while (c>='0' && c<='9')
{
ans=ans*10+c-'0';
c=getchar();
}
x=ans*f;
return ;
}
int f[maxn][maxn2];
int main()
{
read(n);read(m);read(k);
for (int i=1;i<=n;i++)
{
read(x[i]);
read(y[i]);
low[i]=0;
high[i]=m+1;
}
memset(p,0,sizeof(0));
for (int i=1;i<=k;i++)
{
int xx;
read(xx);
read(low[xx]);
read(high[xx]);
p[xx]=1;
}
for (int i=1;i<=n;i++)
for (int j=0;j<=m;j++) f[i][j]=INF;
for (int i=0;i<=m+1;i++)
f[0][i]=0;
f[0][0]=INF;
for (int i=1;i<=n;i++)
{
for (int j=x[i];j<=high[i];j++)
{
if (j==m)
for (int w=m-x[i];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);
f[i][j]=min(f[i][j],f[i][j-x[i]]+1);
}
for (int j=max(1,low[i]+1);j<=min(m-y[i],high[i]-1);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]=INF;
for (int j=high[i];j<=m;j++) f[i][j]=INF;
}
int ans=INF;
int cnt=k;
for(int i=n;i>=1;i--)
{
for(int j=low[i]+1;j<=high[i]-1;j++)
{
ans=min(ans,f[i][j]);
}
if(ans<INF)
{
break;
}
if(p[i]==1)
{
k--;
}
}
if(cnt==k)
{
cout<<
4000
1<<endl<<ans<<endl;
}
else
{
printf("0\n%d",k);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: