洛谷2157 学校食堂(状压DP)

传送门

【题目分析】

用命分析,这个数据范围很状压。。。。。。然后就状压啊。

数组dp[i][j][k]表示前i-1个人已经拿到菜,j枚举i以及他后面7个的拿菜情况,k表示上一个吃饭的位置(相对的)

注意一下枚举的上下界即可。

【代码~】

#include
using namespace std;
const int MAXN=1e3+10;
const int INF=0x3f3f3f3f;

int T;
int n,ans;
int dp[MAXN][1<<9][20];
struct stu{
	int x,y;
}st[MAXN];

int Read(){
	int i=0,f=1;
	char c;
	for(c=getchar();(c>'9'||c<'0')&&c!='-';c=getchar());
	if(c=='-')
	  f=-1,c=getchar();
	for(;c>='0'&&c<='9';c=getchar())
	  i=(i<<3)+(i<<1)+c-'0';
	return i*f;
}

int calc(int a,int b)
{
    if(a==0) 
	  return 0;
    return st[a].x^st[b].x; 
}

void solve()
{
    for(int i=1;i<=n+1;i++){
        for(int j=0;j<(1<<8);j++){
            for(int k=-8;k<=7;k++){
                dp[i][j][k+8]=INF;
            }
        }
    }
    dp[1][0][7]=0;
    for(int i=1;i<=n;i++){
        for(int j=0;j<(1<<8);j++){
            for(int k=-8;k<=7;k++){
                if(dp[i][j][k+8]>1][k+7]=min(dp[i][j][k+8],dp[i+1][j>>1][k+7]);
                }
                else{
                    int r=INF;
                    for(int l=0;l<8;l++){
                        if(!(j&(1<r) 
							  break;
                            r=min(r,i+l+st[i+l].y);
                            dp[i][j+(1<

 

你可能感兴趣的:(————DP————)