P1941 飞扬的小鸟
P1941 飞扬的小鸟
算法:
状态:设
-
上升 :完全背包 转移方式
-
下降 :
01 背包 转移方式 -
超过
m 变为m : 特判
代码:
for(int i=1;i<=n;i++) Low[i]=1,High[i]=m;
for(int i=1;i<=k;i++) p=rd(),e[p]=1,Low[p]=rd()+1,High[p]=rd()-1;
memset(g,inf,sizeof(g));
for(int i=1;i<=m;i++) g[i]=0;
for(int i=1;i<=n;i++)
{
memset(f,inf,sizeof(f));
for(int j=x[i];j<=x[i]+m;j++) f[j]=min(f[j-x[i]]+1,g[j-x[i]]+1); // 完全背包
for(int j=m+1;j<=m+x[i];j++) f[m]=min(f[j],f[m]); // 特判超过 m
for(int j=1;j<=m-y[i];j++) f[j]=min(f[j],g[j+y[i]]); // 01 背包
for(int j=1;j<Low[i];j++) f[j]=inf;
for(int j=High[i]+1;j<=m;j++) f[j]=inf; // 不可行方案
if(e[i]) for(int j=Low[i];j<=High[i];j++) if(f[j]<inf) { cnt++; break; } // 统计通过的管道数
memcpy(g,f,sizeof(g));
}
for(int i=1;i<=m;i++) ans=min(ans,g[i]);
if(ans!=inf) printf("1\n%d\n",ans);
else printf("0\n%d\n",cnt);