noip提高組2014 飛揚的小鳥
阿新 • • 發佈:2019-02-01
DP 用可重複揹包優化
程式碼較長 注意細節
#include<string> #include<cstring> #include<cmath> #include<queue> #include<iostream> #include<algorithm> #include<vector> #include<cstdio> #include<cstdlib> using namespace std; int shang[10010]; int xia[10010]; int up[10010]; int down[10010]; int f[10010][1010]; int n,m,k; bool exist[10010]; int main() { //freopen("bird.in","r",stdin); //("bird.out","w",stdout); int i,j,s,t; scanf("%d%d%d",&n,&m,&k); for(i=0;i<n;i++) { scanf("%d%d",&shang[i],&xia[i]); } for(i=1;i<=n;i++) { down[i]=0; up[i]=m+1; } for(i=1;i<=k;i++) { scanf("%d%d%d",&j,&s,&t); down[j]=s; exist[j]=1; up[j]=t; } for(i=1;i<=n;i++) { for(j=0;j<=m;j++) { f[i][j]=1000000000; } } f[0][0]=1000000000; for(i=1;i<=n;i++) { for(j=1;j<=m;j++) { if(j>=shang[i-1]) { f[i][j]=min(f[i][j],f[i-1][j-shang[i-1]]+1); f[i][j]=min(f[i][j],f[i][j-shang[i-1]]+1); } if(j==m) { for(k=m-shang[i-1];k<=m;k++) { f[i][j]=min(f[i-1][k]+1,f[i][j]); f[i][j]=min(f[i][j],f[i][k]+1); } } } for(j=1;j<=m;j++) { if(j+xia[i-1]<=m) f[i][j]=min(f[i][j],f[i-1][j+xia[i-1]]); } for(j=0;j<=down[i];j++) f[i][j]=1000000000; for(j=up[i];j<=m;j++) f[i][j]=1000000000; } bool hehe=0; int ans=1000000000; for(i=down[n]+1;i<=up[n]-1;i++) { if(f[n][i]<ans) { hehe=1; ans=f[n][i]; } } if(hehe) { cout<<"1"<<endl<<ans<<endl; return 0; } for(i=n-1;i>=0;i--) { for(j=down[i]+1;j<up[i];j++) { if(f[i][j]<1000000000) { cout<<"0"<<endl; k=i; hehe=1; break; } } if(hehe) break; } int tot=0; for(i=0;i<=k;i++) { if(exist[i]) tot++; } cout<<tot; return 0; }