官方的链接:http://www.byvoid.com/blog/byvoid-wow-stage-3/
本博客不再给出题目。
用的O(N^2)的算法。类似USACO的浮水法。
f[i][j] = max{
f[i – 1][j – 1]
f[i – 1][j]
f[i – 1][j + 1]
} + a[i][j]
设f[i][j]是第i天过去后,存下了j的燃料。设l是第i天骗的燃料数。k是上一天剩下的燃料数。
k + l = n[i] + j,推出k = n[i] + j – l。
f[i][j] = min{f[i][j],f[i – 1][k] + l * b[i] + j * w}。
多状态的宽搜。用state表示所有钥匙的状态。第i个钥匙对应的位置为1 << (i – 1)。
v[state][i][j]代表state状态下,(i,j)这个位置是否到过。
第一题
#include <stdio.h> #include <iostream> #define MAXN 200001 using namespace std; struct ss { int l,r; } a[MAXN]; bool have[MAXN]; int ans,n; void flo(int l,int r,int x,int co) { if (l >= r) return; if (have[co]) return; if (x > n) { have[co] = 1; ++ans; return; } if (have[co]) return; if (a[x].l >= l) flo(l,min(a[x].l,r),x + 1,co); if (a[x].r <= r) flo(max(a[x].r,l),r,x + 1,co); } int main() { freopen("punch.in","r",stdin); freopen("punch.out","w",stdout); scanf("%d",&n); for (int i = 1;i <= n;++i) scanf("%d%d",&a[i].l,&a[i].r); for (int i = 1;i <= n;++i) flo(a[i].l,a[i].r,i + 1,i); printf("%d\n",ans); return 0; }
第二题
#include <stdio.h> #include <string.h> #define MAXN 1010 int f[2][MAXN],a[MAXN]; int n,m,ans,now,last; int main() { freopen("azshara.in","r",stdin); freopen("azshara.out","w",stdout); scanf("%d%d",&m,&n); now = 1; for (int i = 1;i <= n;++i) { last = now; now ^= 1; for (int j = 1;j <= m;++j) scanf("%d",&a[j]); memset(f[now],255,sizeof(f[now])); for (int j = 1;j <= m;++j) if (a[j] != -1) { if ((j - 1 > 0) && (f[last][j - 1] != -1) && (f[last][j - 1] + a[j] > f[now][j])) f[now][j] = f[last][j - 1] + a[j]; if ((f[last][j] != -1) && (f[last][j] + a[j] > f[now][j])) f[now][j] = f[last][j] + a[j]; if ((j + 1 <= m) && (f[last][j + 1] != -1) && (f[last][j + 1] + a[j] > f[now][j])) f[now][j] = f[last][j + 1] + a[j]; } } for (int j = 1;j <= m;++j) if (f[now][j] > ans) ans = f[now][j]; printf("%d\n",ans); return 0; }
第三题
#include <stdio.h> #define MAXT 1010 #define MAXINT 10000000 int b[MAXT],n[MAXT]; int t,v,a,w,x,y; int f[MAXT][110],d[MAXT][110],ans[MAXT]; int main() { freopen("arugal.in","r",stdin); freopen("arugal.out","w",stdout); scanf("%d%d%d%d",&t,&v,&a,&w); for (int i = 0;i <= t;++i) for (int j = 0;j <= v;++j) f[i][j] = MAXINT; f[0][0] = 0; for (int i = 1;i <= t;++i) { scanf("%d%d",&n[i],&b[i]); for (int j = 0;j <= v;++j) for (int l = 0;l <= a;++l) { int k = n[i] + j - l; if ((k >= 0) && (k <= v)) if (f[i - 1][k] + j * w + b[i] * l < f[i][j]) { f[i][j] = f[i - 1][k] + j * w + b[i] * l; d[i][j] = l; } } } int mi = MAXINT; y = 0; mi = f[t][0]; for (int i = t;i > 0;--i) { ans[i] = d[i][y]; y = n[i] + y - d[i][y]; } printf("%d\n",mi); for (int i = 1;i <= t;++i) printf("%d\n",ans[i]); return 0; }
第四题
#include <stdio.h> #include <iostream> #define MAXN 51 #define MAXL 10000000 using namespace std; struct ss { int x,y,dis,state; } q[MAXL]; int n,m,tex,tey,x,y,state,dis,l,r; int a[MAXN][MAXN]; bool v[65527][MAXN][MAXN]; int xx[4] = {1,-1,0,0}; int yy[4] = {0,0,1,-1}; void add(int x,int y,int di,int state) { if ((x == n) && (y == n)) { printf("%d\n",dis + 1); exit(0); } if (a[x][y] < 0) return; if (a[x][y] == 0) { r = (r + 1) % MAXL; q[r].x = x; q[r].y = y; q[r].dis = di + 1; q[r].state = state; v[state][x][y] = 1; return; } if (a[x][y] <= m) { state |= (1 << (a[x][y] - 1)); r = (r + 1) % MAXL; q[r].x = x; q[r].y = y; q[r].dis = di + 1; q[r].state = state; v[state][x][y] = 1; return; } if ((state >> (a[x][y] - m - 1)) & 1) { r = (r + 1) % MAXL; q[r].x = x; q[r].y = y; q[r].dis = di + 1; q[r].state = state; v[state][x][y] = 1; return; } } bool inmap(int x,int y) { return (x > 0) && (x <= n) && (y > 0) && (y <= n); } int main() { freopen("syndicate.in","r",stdin); freopen("syndicate.out","w",stdout); scanf("%d%d",&n,&m); for (int i = 1;i <= n;++i) for (int j = 1;j <= n;++j) scanf("%d",&a[i][j]); for (int i = 1;i <= n;++i) for (int j = 1;j <= n;++j) if (a[i][j] == -2) for (int k = 0;k < 4;++k) { tex = i + xx[k]; tey = j + yy[k]; if (inmap(tex,tey) && (a[tex][tey] != -2)) a[tex][tey] = -1; } /* for (int i = 1;i <= n;++i) { for (int j = 1;j <= n;++j) printf("%d ",a[i][j]); printf("\n"); } */ q[0].x = q[0].y = 1; while (l <= r) { x = q[l].x; y = q[l].y; dis = q[l].dis; state = q[l].state; for (int i = 0;i < 4;++i) { tex = x + xx[i]; tey = y + yy[i]; if (inmap(tex,tey) && (!v[state][tex][tey])) add(tex,tey,dis,state); } l = (l + 1) % MAXL; } }