bzoj 1226 [SDOI2009]学校食堂Dining 状压dp
2016-11-24 16:03
288 查看
设f[i][j][k]表示当前最早的没打饭的人为i,i后面的7个人打过的状态为j,上一个打饭的人为i+k的方案数。
不过需要注意上一个打的人和当前人的差最大是8。。。
然后转移时可能是后面的人打饭或当前人打饭。
注意判一下状态非法。。。
不过需要注意上一个打的人和当前人的差最大是8。。。
然后转移时可能是后面的人打饭或当前人打饭。
注意判一下状态非法。。。
#include <bits/stdc++.h> using namespace std; #define A 20 #define N 1100 int f [(1<<7)+10][51]; int T,n,ans,inf; int a ,b ; void upd(int &x,int y){x=min(x,y);} int main() { //freopen("tt.in","r",stdin); scanf("%d",&T); while(T--) { scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d%d",&a[i],&b[i]); if(n==1){puts("0");continue;} memset(f,0x3f,sizeof(f));ans=inf=f[0][0][0]; for(int i=2,now=b[1]+1;i<=now;i++) { f[1][1<<i-2][i-1+A]=0; now=min(now,b[i]+i); } f[2][0][A-1]=0; for(int i=1;i<=n;i++) for(int j=0;j<1<<b[i];j++) for(int k=0;k<=A*2;k++) if(f[i][j][k]!=inf) { int t=j,now=i+1; while(t&1)t>>=1,now++;t>>=1; upd(f[now][t][i-now+A],f[i][j][k]+(a[i]^a[i+k-A])); now=b[i]; for(int t=0;t<now;t++) if(i+t+1<=n&&!(j>>t&1)) { upd(f[i][j|(1<<t)][(i+t+1)-i+A],f[i][j][k]+(a[i+t+1]^a[i+k-A])); now=min(now,b[i+t+1]+t+1); } } for(int i=1;i<=n;i++) for(int k=0;k<=A*2;k++) if(i+b[i]>=n&&i+k-A>=1&&i+k-A<=n) ans=min(ans,f[i][(1<<n-i)-1][k]+(a[i+k-A]^a[i])); printf("%d\n",ans); } return 0; }
相关文章推荐
- bzoj1226 [SDOI2009]学校食堂Dining
- BZOJ 1226 [SDOI2009] 学校食堂Dining
- BZOJ 1226: [SDOI2009]学校食堂Dining [DP 状压]
- BZOJ1226 [SDOI2009]学校食堂Dining 【状压dp】
- [BZOJ1226][SDOI2009]学校食堂Dining-状压DP
- 【BZOJ1226】【SDOI2009】学校食堂
- bzoj 1226 [SDOI2009]学校食堂Dining(状压DP)
- BZOJ 1226: [SDOI2009]学校食堂Dining
- BZOJ 1226: [SDOI2009]学校食堂Dining 状压DP
- bzoj1226 [SDOI2009]学校食堂Dining (状压DP)
- BZOJ 1226: [SDOI2009]学校食堂Dining
- BZOJ1226 SDOI2009学校食堂
- NKOJ-3790 BZOJ-1226 [SDOI2009]学校食堂Dining
- BZOJ 1226: [SDOI2009]学校食堂Dining
- BZOJ 1226 [SDOI2009]学校食堂Dining
- 【bzoj1226】【[SDOI2009]学校食堂Dining】状压dp
- SDOI2009 BZOJ1226 学校食堂dining
- 【SDOI2009】bzoj1226 学校食堂
- BZOJ1226 SDOI2009学校食堂(状压dp)
- BZOJ 1226 [SDOI2009]学校食堂Dining ——状压DP