BZOJ1226 SDOI2009学校食堂
2018-01-29 09:08
162 查看
这题状压DP太神了。
g[i][j][k]表示前i-1个人都已打到饭,自己和后七个人打饭的情况是j,当前最后一个打饭的与i的关系是k
如果j&1==1说明当前这个人也打了饭,那么可以转移到g[i+1][j>>1][k-1]因为i+1+k-1==i+k
然后我们再枚举当前哪个人要打饭计算状态即可。
学习了hzwer的代码
#include<bits/stdc++.h> #define f(a,b,c) (g[a][b][c+8]) using namespace std; int g[1005][256][16],ins[1005],tas[1005],n,T; int calc(int x,int y) { if(!x)return 0; return tas[x]^tas[y]; } int main() { scanf("%d",&T); while(T--) { memset(g,0x3f,sizeof(g)); f(1,0,-1)=0;scanf("%d",&n); for(int i=1;i<=n;++i)scanf("%d%d",&tas[i],&ins[i]); for(int i=1;i<=n;++i) for(int j=0;j<(1<<8);++j) for(int k=-8;k<=7;++k) if(j&1) { f(i+1,j>>1,k-1)=min(f(i+1,j>>1,k-1),f(i,j,k)); } else { int r=1e9; for(int p=0;p<=7;++p) if((j&(1<<p))==0) { if(i+p>r)break; r=min(r,i+p+ins[i+p]); f(i,j|(1<<p),p)=min(f(i,j|(1<<p),p),f(i,j,k)+calc(i+k,i+p)); } } int ans=1e9; for(int k=-8;k<=-1;++k) ans=min(ans,f(n+1,0,k)); printf("%d\n",ans); } return 0; }
相关文章推荐
- [BZOJ1226][SDOI2009][状态压缩DP]学校食堂Dining
- bzoj1226 [SDOI2009]学校食堂Dining 状压DP
- bzoj1226: [SDOI2009]学校食堂Dining
- BZOJ 1226: [SDOI2009]学校食堂Dining [DP 状压]
- bzoj1226 [SDOI2009]学校食堂Dining
- BZOJ 1226 [SDOI2009] 学校食堂Dining
- [bzoj 1226] [SDOI2009]学校食堂Dining:状态压缩的奥妙
- bzoj 1226: [SDOI2009]学校食堂Dining
- [BZOJ1226][SDOI2009]学校食堂(状压DP)
- 【bzoj1226】【[SDOI2009]学校食堂Dining】状压dp
- BZOJ 1226: [SDOI2009]学校食堂Dining 状压DP
- bzoj 1226: [SDOI2009]学校食堂Dining
- 【BZOJ1226】【SDOI2009】学校食堂
- bzoj 1226 [SDOI2009]学校食堂Dining(状压DP)
- BZOJ 1226: [SDOI2009]学校食堂Dining
- [BZOJ]1226 [SDOI2009]学校食堂Dining
- bzoj 1226 [SDOI2009]学校食堂Dining 状压dp
- BZOJ 1226 [SDOI2009]学校食堂Dining
- 1226: [SDOI2009]学校食堂Dining - BZOJ
- 【SDOI2009】bzoj1226 学校食堂