您的位置:首页 > 其它

noip2014 飞扬的小鸟 DP

2016-11-13 08:35 344 查看
这道题向上是完全背包 dp[i][j+cx[i-1]] = min( dp[i][j]+1 , dp[i][j+cx[i-1]] ).

向下是01背包 dp[i][j] = min ( dp[i][j] , dp[i-1][j+cy[i-1]] ).注意先向上转移。

然后用管子覆盖掉。

然后向后递推点一下的情况dp[i+1][j+cx[i]] = dp[i][j]+1;

时间复杂度n*m;

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int cx[10005],cy[10005];
struct P{
int x,h,l;
void read()
{scanf("%d%d%d",&x,&h,&l);}
}p[10005];
bool cmp(P a,P b)
{return a.x<b.x;}
int dp[10005][1005];
int inf=1e9;
int main()
{
int n,m,k;
scanf("%d%d%d",&n,&m,&k);
for(int i=0;i<n;i++)
scanf("%d%d",&cx[i],&cy[i]);
for(int i=1;i<=k;i++)
p[i].read();
sort(p+1,p+k+1,cmp);
for(int i=1;i<=n;i++)
for(int j=0;j<=m;j++)
dp[i][j]=inf;
int H=1;
for(int j=0;j<=m;j++)
{
if(j+cx[0]<=m)
dp[1][j+cx[0]]=min(dp[1][j+cx[0]],dp[0][j]+1);
else
dp[1][m]=min(dp[1][m],dp[0][j]+1);
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
if(j+cx[i-1]<=m)//           shangsheng
dp[i][j+cx[i-1]]=min(dp[i][j+cx[i-1]],dp[i][j]+1);
else dp[i][m]=min(dp[i][m],dp[i][j]+1);
}
for(int j=1;j<=m;j++)
{
if(j+cy[i-1]<=m)//           qianyige xialuo
dp[i][j]=min(dp[i-1][j+cy[i-1]],dp[i][j]);
}
if(H<=k&&p[H].x==i)//
{
for(int j=0;j<=p[H].h;j++) dp[i][j]=inf;
for(int j=m;j>=p[H].l;j--) dp[i][j]=inf;
H++;
}
for(int j=1;j<=m;j++)
{
if(j+cx[i]<=m)
dp[i+1][j+cx[i]]=min(dp[i+1][j+cx[i]],dp[i][j]+1);
else
dp[i+1][m]=min(dp[i+1][m],dp[i][j]+1);
}
}
int ans=inf;
for(int i=1;i<=m;i++)
ans=min(ans,dp
[i]);
if(ans!=inf)
{
puts("1");
cout<<ans;
}
else
{
puts("0");int i;bool h=0;
for(i=k;i>=1;i--)
{
for(int j=1;j<=m;j++)
{
if(dp[p[i].x][j]!=inf)
{h=1;break;}
}
if(h) break;
}
printf("%d",i);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  dp