现在的位置: 首页 > 算法 > 正文

【状压DP】【bzoj 1226】: [SDOI2009]学校食堂Dining

2017年04月21日 算法 ⁄ 共 1603字 ⁄ 字号 评论关闭

http://www.lydsy.com/JudgeOnline/problem.php?id=1226


及其恶心的状压,又抄标程去了。。。

//#define _TEST _TEST
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <cmath>
#include <algorithm>
using namespace std;
/************************************************
Code By willinglive    Blog:http://willinglive.cf
************************************************/
#define rep(i,l,r) for(int i=(l),___t=(r);i<=___t;i++)
#define per(i,r,l) for(int i=(r),___t=(l);i>=___t;i--)
#define MS(arr,x) memset(arr,x,sizeof(arr))
#define LL long long
#define INE(i,u,e) for(int i=head[u];~i;i=e[i].next)
inline const int read()
{int r=0,k=1;char c=getchar();for(;c<'0'||c>'9';c=getchar())if(c=='-')k=-1;
for(;c>='0'&&c<='9';c=getchar())r=r*10+c-'0';return k*r;}
/////////////////////////////////////////////////
const int inf=0x3f3f3f3f;
int n;
int T[1010],B[1010];
int _dp[1010][1<<8][18];
#define dp(i,j,k) _dp[i][j][(k)+9]
/////////////////////////////////////////////////
void MIN(int &a,const int &b){if(a>b)a=b;}
/////////////////////////////////////////////////
void input()
{
    n=read();
    rep(i,1,n) T[i]=read(), B[i]=read();
}
void solve()
{
	MS(_dp,0x3f);
	int all=(1<<8)-1;
	dp(1,0,-1)=0;
	rep(i,1,n) rep(S,0,all) rep(j,-8,7) if(dp(i,S,j)<inf)
	{
		if(S&1) //当前的人已经选走了 
		{
			dp(i+1,S>>1,j-1)=dp(i,S,j);
		}
		else
		{
			int limit=inf;
			rep(k,0,7)
			{
				if(S&(1<<k)) continue;
				if(i+k>limit) break;
				MIN(limit,i+k+B[i+k]);
				MIN(dp(i,S|(1<<k),k),dp(i,S,j)+(i+j==0?0:(T[i+j]^T[i+k])));//把i+k放在i的前面
			}
		}
	}
	int ans=inf;
	rep(i,-8,-1) MIN(ans,dp(n+1,0,i));
	cout<<ans<<endl;
}
/////////////////////////////////////////////////
int main()
{
    #ifndef _TEST
    freopen("std.in","r",stdin); freopen("std.out","w",stdout);
    #endif
    rep(i,1,read())
    input(),solve();
    return 0;
}

抱歉!评论已关闭.