BZOJ1226 SDOI2009学校食堂

这题状压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的代码

 1 #include<bits/stdc++.h>
 2 #define f(a,b,c) (g[a][b][c+8])
 3 using namespace std;
 4 int g[1005][256][16],ins[1005],tas[1005],n,T;
 5 int calc(int x,int y)
 6 {
 7     if(!x)return 0;
 8     return tas[x]^tas[y];
 9 }
10 int main()
11 {
12     scanf("%d",&T);
13     while(T--)
14     {
15         memset(g,0x3f,sizeof(g));
16         f(1,0,-1)=0;scanf("%d",&n);
17         for(int i=1;i<=n;++i)scanf("%d%d",&tas[i],&ins[i]);
18         for(int i=1;i<=n;++i)
19             for(int j=0;j<(1<<8);++j)
20                 for(int k=-8;k<=7;++k)
21                 if(j&1)
22                 {
23                     f(i+1,j>>1,k-1)=min(f(i+1,j>>1,k-1),f(i,j,k));
24                 }
25                 else
26                 {
27                     int r=1e9;
28                     for(int p=0;p<=7;++p)
29                     if((j&(1<<p))==0)
30                     {
31                         if(i+p>r)break;
32                         r=min(r,i+p+ins[i+p]);
33                         f(i,j|(1<<p),p)=min(f(i,j|(1<<p),p),f(i,j,k)+calc(i+k,i+p));
34                     }
35                 }
36         int ans=1e9;
37         for(int k=-8;k<=-1;++k)
38         ans=min(ans,f(n+1,0,k));
39         printf("%d\n",ans);
40     }
41     return 0;
42 }

原文地址:https://www.cnblogs.com/nbwzyzngyl/p/8375818.html

时间: 2024-12-11 06:06:55

BZOJ1226 SDOI2009学校食堂的相关文章

[BZOJ1226][SDOI2009]学校食堂Dining

试题描述 小F 的学校在城市的一个偏僻角落,所有学生都只好在学校吃饭.学校有一个食堂,虽然简陋,但食堂大厨总能做出让同学们满意的菜肴.当然,不同的人口味也不一定相同,但每个人的口味都可以用一个非负整数表示.由于人手不够,食堂每次只能为一个人做菜.做每道菜所需的时间是和前一道菜有关的,若前一道菜的对应的口味是a,这一道为b,则做这道菜所需的时间为(a or b)-(a and b),而做第一道菜是不需要计算时间的.其中,or 和and 表示整数逐位或运算及逐位与运算,C语言中对应的运算符为"|&q

bzoj1226: [SDOI2009]学校食堂Dining 状压dp

Description 小F 的学校在城市的一个偏僻角落,所有学生都只好在学校吃饭.学校有一个食堂,虽然简陋,但食堂大厨总能做出让同学们满意的菜肴.当然,不同的人口味也不一定相同,但每个人的口味都可以用一个非负整数表示.由于人手不够,食堂每次只能为一个人做菜.做每道菜所需的时间是和前一道菜有关的,若前一道菜的对应的口味是a,这一道为b,则做这道菜所需的时间为(a or b)-(a and b),而做第一道菜是不需要计算时间的.其中,or 和and 表示整数逐位或运算及逐位与运算,C语言中对应的运

【BZOJ1226】[SDOI2009]学校食堂Dining 状压DP

[BZOJ1226][SDOI2009]学校食堂Dining Description 小F 的学校在城市的一个偏僻角落,所有学生都只好在学校吃饭.学校有一个食堂,虽然简陋,但食堂大厨总能做出让同学们满意的菜肴.当然,不同的人口味也不一定相同,但每个人的口味都可以用一个非负整数表示.由于人手不够,食堂每次只能为一个人做菜.做每道菜所需的时间是和前一道菜有关的,若前一道菜的对应的口味是a,这一道为b,则做这道菜所需的时间为(a or b)-(a and b),而做第一道菜是不需要计算时间的.其中,o

【题解】Luogu P2157 [SDOI2009]学校食堂

原题传送门:P2157 [SDOI2009]学校食堂 一看题目就知道是状压dp 设f[i][j][k]表示第1到i-1个人都吃完了饭,第i个人以及后面的7个人是否打饭的状态为j,当前最后打饭的人的编号为i+k(-8<=k<=7) 开始设计状态转移方程 当j&1为真,表示i之后的7个人中,不再会有人插队到i之前 可得:f[i + 1][j >> 1][k - 1]=Min(f[i + 1][j >> 1][k -1],f[i][j][k]) 当j&1为假,

[SDOI2009]学校食堂

题目描述 小F 的学校在城市的一个偏僻角落,所有学生都只好在学校吃饭.学校有一个食堂,虽然简陋,但食堂大厨总能做出让同学们满意的菜肴.当然,不同的人口味也不一定相同,但每个人的口味都可以用一个非负整数表示. 由于人手不够,食堂每次只能为一个人做菜.做每道菜所需的时间是和前一道菜有关的,若前一道菜的对应的口味是a,这一道为b,则做这道菜所需的时间为(a or b)-(a and b),而做第一道菜是不需要计算时间的.其中,or 和and 表示整数逐位或运算及逐位与运算,C语言中对应的运算符为"|&

bzoj 1226 [SDOI2009]学校食堂Dining(状压DP)

Description 小F 的学校在城市的一个偏僻角落,所有学生都只好在学校吃饭.学校有一个食堂,虽然简陋,但食堂大厨总能做出让同学们满意的菜肴.当然,不同的人口味也不一定相同,但每个人的口味都可以用一个非负整数表示.由于人手不够,食堂每次只能为一个人做菜.做每道菜所需的时间是和前一道菜有关的,若前一道菜的对应的口味是a,这一道为b,则做这道菜所需的时间为(a or b)-(a and b),而做第一道菜是不需要计算时间的.其中,or 和and 表示整数逐位或运算及逐位与运算,C语言中对应的运

P2157 [SDOI2009]学校食堂Dining

题目描述 小F 的学校在城市的一个偏僻角落,所有学生都只好在学校吃饭.学校有一个食堂,虽然简陋,但食堂大厨总能做出让同学们满意的菜肴.当然,不同的人口味也不一定相同,但每个人的口味都可以用一个非负整数表示. 由于人手不够,食堂每次只能为一个人做菜.做每道菜所需的时间是和前一道菜有关的,若前一道菜的对应的口味是a,这一道为b,则做这道菜所需的时间为(a or b)-(a and b),而做第一道菜是不需要计算时间的.其中,or 和and 表示整数逐位或运算及逐位与运算,C语言中对应的运算符为"|&

[SDOI2009]学校食堂Dining

Description 小F 的学校在城市的一个偏僻角落,所有学生都只好在学校吃饭.学校有一个食堂,虽然简陋,但食堂大厨总能做出让同学们满意的菜肴.当然,不同的人口味也不一定相同,但每个人的口味都可以用一个非负整数表示.由于人手不够,食堂每次只能为一个人做菜.做每道菜所需的时间是和前一道菜有关的,若前一道菜的对应的口味是a,这一道为b,则做这道菜所需的时间为(a or b)-(a and b),而做第一道菜是不需要计算时间的.其中,or 和and 表示整数逐位或运算及逐位与运算,C语言中对应的运

P2157 [SDOI2009]学校食堂

题目描述 小F 的学校在城市的一个偏僻角落,所有学生都只好在学校吃饭.学校有一个食堂,虽然简陋,但食堂大厨总能做出让同学们满意的菜肴.当然,不同的人口味也不一定相同,但每个人的口味都可以用一个非负整数表示. 由于人手不够,食堂每次只能为一个人做菜.做每道菜所需的时间是和前一道菜有关的,若前一道菜的对应的口味是a,这一道为b,则做这道菜所需的时间为(a or b)-(a and b),而做第一道菜是不需要计算时间的.其中,or 和and 表示整数逐位或运算及逐位与运算,C语言中对应的运算符为“|”