标签:
这是一道典型的DP,f[i][j],i表示横坐标,j表示纵坐标,每一个横坐标都用完全背包来计算,其中有些特判,请在程序中体会:
#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #define maxn 10010 using namespace std; const int inf=0x7ffffff; int n,m,k,p,l,h; int x[maxn],y[maxn],down[maxn],up[maxn]; int f[maxn][1001]; int main() { freopen("bird.in","r",stdin); freopen("bird.out","w",stdout); scanf("%d%d%d",&n,&m,&k); for (int i=0;i<n;i++) scanf("%d%d",&x[i],&y[i]); for (int i=1;i<=n;i++) { down[i]=0; up[i]=m+1; } for(int i=1;i<=k;i++) { cin>>p>>l>>h; down[p]=l; up[p]=h; } for (int i=1;i<=n;i++) for (int j=0;j<=m;j++) f[i][j]=inf; f[0][0]=inf; int arrive=k; for (int i=1;i<=n;i++) { for (int j = 1; j <= m; j++) { if(j >= x[i-1]) { f[i][j] = min(f[i][j], f[i-1][j-x[i-1]] + 1); f[i][j] = min(f[i][j], f[i][j-x[i-1]] + 1); } if(j == m) { for(int k=j-x[i-1];k<=m;k++) { f[i][j] = min(f[i][j], f[i-1][k] + 1); f[i][j] = min(f[i][j], f[i][k] + 1); } } } for (int j = down[i]+1; j <= up[i]-1; ++j) if( j + y[i-1] <= m) f[i][j] = min(f[i][j], f[i-1][j+y[i-1]]); for (int j = 1; j <= down[i]; j++) f[i][j] = inf; for (int j = up[i]; j <= m; j++) f[i][j] = inf; } int cnt = k, ans = inf; for (int i = n; i >= 1; i--) { for (int j = down[i]+1; j <= up[i]-1; ++j) if (f[i][j] < inf) ans = min(ans, f[i][j]); if (ans != inf) break; if (up[i] <= m) cnt --; } if(cnt==k) printf("1\n%d\n", ans); else printf("0\n%d\n", cnt); return 0; }
清清正正射命丸文是也~
标签:
原文地址:http://www.cnblogs.com/Ayateriteri/p/5689796.html