坑人啊樸素的dp 75分
用了完全揹包才是80分,結果普遍偏小 為什麼啊啊啊啊啊 等以後再寫一遍吧
//80 #include<iostream> #include<cstdio> #include<cstring> using namespace std; const int N=10005,M=1005,INF=1e9; int n,m,k, x,y,p,ll,hh; int up[N],down[N],l[N],h[N], has[N]; int f[N][M]; int ans=INF; void dp(){ for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) f[i][j]=INF; for(int i=1;i<=n;i++) for(int j=l[i]+1;j<h[i];j++){ int &now=f[i][j]; if(j==m) for(int z=h[i-1]-1;z>l[i-1];z--){ if(z==m) now=min(now,f[i-1][z]+1); else if((m-z)%up[i-1]==0) now=min(now,f[i-1][z]+(m-z)/up[i-1]); else now=min(now,f[i-1][z]+(m-z)/up[i-1]+1); } else{ if(j-up[i-1]>l[i]&&j-up[i-1]<h[i]) now=min(now,f[i][j-up[i-1]]+1); if(j-up[i-1]>l[i-1]&&j-up[i-1]<h[i]) now=min(now,f[i-1][j-up[i-1]]+1); if(l[i-1]<j+down[i-1]&&j+down[i-1]<h[i-1]) now=min(now,f[i-1][j+down[i-1]]); } } } int main(){ scanf("%d%d%d",&n,&m,&k); for(int i=0;i<=n;i++) h[i]=m+1; for(int i=0;i<n;i++){ scanf("%d%d",&x,&y); up[i]=x; down[i]=y; } for(int i=0;i<k;i++){ scanf("%d%d%d",&p,&ll,&hh); l[p]=ll; h[p]=hh; has[p]=1; } dp(); for(int j=l[n]+1;j<h[n];j++) ans=min(ans,f[n][j]); if(ans==INF){ cout<<0<<"\n"; int flag=0; for(int i=n-1;i>=0;i--){ for(int j=l[i]+1;j<h[i];j++){ if(f[i][j]<INF) { int tmp=0; for(int z=0;z<=i;z++) tmp+=has[z]; cout<<tmp; flag=1;break; } } if(flag) break; } }else{ cout<<1<<"\n"<<ans; } // cout<<"\n\n\n"; // for(int i=0;i<=n;i++) cout<<has[i]<<"\n"; // for(int i=0;i<=n;i++) // for(int j=l[i]+1;j<h[i];j++){ // printf("%d %d %d\n",i,j,f[i][j]); // } }