学校食堂

洛谷

瞻前顾后的状压dp

#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;
}
View Code

 

posted @ 2019-10-23 10:33  凉如水  阅读(103)  评论(0编辑  收藏  举报