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;
}
本文深入探讨了一道复杂的状压动态规划问题,并提供了一份详细的代码解析。通过对问题的逐步分解,介绍了如何利用状压技巧解决特定场景下的优化问题。

136

被折叠的 条评论
为什么被折叠?



