BZOJ 1226 [SDOI2009]学校食堂Dining ——状压DP
看到B<=8,直接状态压缩即可。
dp[i][j][k]表示当前相对位置是关于i的,并且i以前的已经就餐完毕,j表示i和之后的就餐情况,k表示上一个就餐的人的相对位置。
然后Dp即可
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; #define F(i,j,k) for (int i=j;i<=k;++i) #define D(i,j,k) for (int i=j;i>=k;--i) #define inf 0x3f3f3f3f #define maxn 1005 const int buf=8; int dp[maxn][258][17]; int T,t[maxn],b[maxn],n; int main() { scanf("%d",&T); while (T--) { scanf("%d",&n); F(i,1,n) scanf("%d%d",&t[i],&b[i]); memset(dp,0x3f,sizeof dp); dp[1][0][-1+buf]=0; F(i,1,n) F(j,0,(1<<8)-1) F(k,-8,7) if (dp[i][j][k+buf]<inf) { if (j&1) dp[i+1][j>>1][k+buf-1]=min(dp[i+1][j>>1][k+buf-1],dp[i][j][k+buf]); else { int lim=inf; F(l,0,7) if (!(j&(1<<l))) { if (i+l>lim) break; lim=min(lim,i+l+b[i+l]); dp[i][j|(1<<l)][l+buf]=min(dp[i][j|(1<<l)][l+buf],dp[i][j][k+buf]+(k+i==0?0:t[k+i]^t[l+i])); } } } int ans=0x3f3f3f3f; F(i,-8,7) ans=min(ans,dp[n+1][0][i+buf]); printf("%d\n",ans); } }