2017.5.8 飞扬的小鸟 失败总结

来源:互联网 发布:java字符串转date 编辑:程序博客网 时间:2024/06/05 05:43

      这个题明显n*m*m是过不了的,但想了一晚上也没有什么好的办法可以单次o(1);

      后来才明白,原来题读错了,原来不止可以从不同阶段转移、、还可以同阶段转移、、、

      完全被传统背包限制住了、这种题应该利用所有可利用的决策信息,

        但是,这个题细节异常的多:

      1、处理上升必须在处理下落以先,不然会导致同时进行下落与上升,不符题意

      2、处理上升不止要在缝隙内,缝隙外的也要算(因为同阶段累加算的相当于是前缀和,这一阶段缝隙下端开始按的可能不止一次,所以每一个都要有值、)


要避开这些问题,一次通过,必须做到:

1、在写的时候注意决策的顺序

2、在写的时候注意打错问题

3、在写的时候注意你想的意义和代码的意义是否相符,每个语句是否完全实现了它的作用。


#include<iostream>#include<cstdio>using namespace std;#include<cstring> int cnt,i,j,k,n,m,f[2][300001],up[300001],down[300001],shang[300001],xia[300001],now,ans=1e9,x,y,z;int main(){scanf("%d%d%d",&n,&m,&k);for(i=1;i<=n;i++){scanf("%d%d",&up[i],&down[i]);shang[i]=m;xia[i]=1;}shang[0]=m;xia[0]=1;memset(f,0x7f,sizeof(f));for(i=1;i<=m;i++)f[now^1][i]=0;for(i=1;i<=k;i++){scanf("%d%d%d",&x,&y,&z);xia[x]=y+1;shang[x]=z-1;}for(i=1;i<=n;i++,now^=1){bool jieshu=1;for(j=1;j<=m;j++){  if(j-up[i]>=xia[i-1]&&j-up[i]<=shang[i-1])f[now][j]=min(f[now^1][j-up[i]]+1,f[now][j]);    if(j-up[i]>=1)f[now][j]=min(f[now][j-up[i]]+1,f[now][j]);//每一个点都可以累加,无关缝隙,当前阶段下面的点是为上面 点击>=2 做准备 }for(z=0;z<=up[i]&&m-z>0;z++){  if(m-z>=xia[i-1]&&m-z<=shang[i-1])f[now][m]=min(f[now][m],f[now^1][m-z]+1);  f[now][m]=min(f[now][m],f[now][m-z]+1);        } for(j=xia[i];j<=shang[i];j++){if(j+down[i]<=shang[i-1]&&j+down[i]>=xia[i-1])f[now][j]=min(f[now][j],f[now^1][j+down[i]]);}    for(j=0;j<=2*m;j++){f[now^1][j]=1e9;}//cout<<i<<":"<<endl;for(j=xia[i];j<=shang[i];j++){//cout<<j<<":"<<f[now][j]<<" ";if(f[now][j]<1e9)jieshu=0;    }//cout<<endl;if(jieshu==1){printf("0\n%d",cnt);//cout<<" "<<i<<" ";return 0;}if(xia[i]!=1||shang[i]!=m)++cnt;}for(i=1;i<=m;i++){ans=min(ans,f[now^1][i]);}printf("1\n%d",ans);}


0 0
原创粉丝点击