学校食堂
瞻前顾后的状压dp
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> #define re return #define inc(i,l,r) for(int i=l;i<=r;++i) using namespace std; template<typename T>inline void rd(T&x) { char c;bool f=0; while((c=getchar())<'0'||c>'9')if(c=='-')f=1; x=c^48; while((c=getchar())>='0'&&c<='9')x=x*10+(c^48); if(f)x=-x; } const int maxn=1005; int t[maxn],b[maxn],n; int f[maxn][1<<8][21]; int main() { // freopen("in.txt","r",stdin); int T; rd(T); while(T--) { rd(n); inc(i,1,n)rd(t[i]),rd(b[i]); memset(f,0x3f3f3f3f,sizeof f); f[1][0][7]=0; inc(i,1,n)inc(j,0,(1<<8)-1)inc(k,-8,7) //前(i-1个人已经做好)现在以及后面7个人的状态,K(最后做的菜市) if(f[i][j][k+8]!=0x3f3f3f3f) { if(j&1)f[i+1][j>>1][k+7]=min(f[i+1][j>>1][k+7],f[i][j][k+8]);//可以进位 else { int ret=0x3f3f3f3f; inc(h,0,7) if(((j>>h)&1)==0) { if(i+h>ret)break;//满足容忍度内 ret=min(ret,i+h+b[i+h]); f[i][j|(1<<h)][h+8]=min(f[i][j|(1<<h)][h+8],f[i][j][k+8]+(i+k?t[i+k]^t[i+h]:0)); } } } int ans=0x3f3f3f3f; inc(i,0,8) ans=min(ans,f[n+1][0][i]); printf("%d\n",ans); } re 0; }