這道題的思想是$dp$。
首先通過簡單推理發現:$(a|b)-(a\&b)=a\hat{} b$。[$(a\ and\ b) - (a\ or\ b) = a\ xor\ b$]
發現對於第$i$個同學的飯菜的選擇受到2方面影響:
是否在前面的某個沒有選擇的同學$>b_i$的位置;
上一次選擇的同學。
觀察資料資訊可知$b_i \leq 7$。
也就是說如果選擇了第$i$個,那麼最多只能選到第$i+7$個同學。前提是第$i$位同學之前全部選完了。
所以我們用狀壓寫。同時記錄上一輪選的同學相對於第$i$位同學的位置,推算得範圍一定在$-8\sim 7$之間(包含兩邊)。
設$f[i][s][x]$為第$i$個之前的同學全部選完,$s$為第$i$到$i+7$同學是否選擇的狀態,$x$同上,
當第$i$位同學已選擇,就可以轉移到$f[i+1][s>>1][x-1]$;
其他任意情況時,當第$i+bit$位同學可以被選擇時(指不超過未選擇的$b[i]$到$b[i+bit-1]$的範圍),可以轉移到$f[i][s | (1 << bit)][bit]$,貢獻為$t[i+x]\hat{} t[i+bit]$,再取最小值即可。
邊界:$f[1][0][-1] = 0$,其餘為$inf$。
注意$x>0$和第一輪的異或結果為$0$,特判一下即可。
因為c++下標不能為負,注意下標偏移。
1 #include 23using
namespace
std;45
#define re register
6#define rep(i, a, b) for (re int i = a; i <= b; ++i)
7#define repd(i, a, b) for (re int i = a; i >= b; --i)
8#define maxx(a, b) a = max(a, b);
9#define minn(a, b) a = min(a, b);
10#define ll long long
11#define inf (1 << 30)
1213 inline int
read()
1920
const
int maxn = 1e3 + 10;21
22int
c, n, t[maxn], b[maxn];
2324
int f[maxn][1
<< 8][16
];25
26int
main() 44}
45 rep(x, 0, 15)46
if (s & 1) minn(f[i+1][s >> 1][x-1
], f[i][s][x]);47}
48}49int ans =inf;
50 rep(i, 0, 8) minn(ans, f[n][1
][i]);
51 printf("
%d\n
", ans);52}
53return0;
54 }
SDOI2009 學校食堂
time limits 1000 ms memory limits 262144 kb detailed limits description 小f 的學校在城市的乙個偏僻角落,所有學生都只好在學校吃飯。學校有乙個食堂,雖然簡陋,但食堂大廚總能做出讓同學們滿意的菜餚。當然,不同的人口味也不一定相同,...
SDOI2009 學校食堂
小f 的學校在城市的乙個偏僻角落,所有學生都只好在學校吃飯。學校有乙個食堂,雖然簡陋,但食堂大廚總能做出讓同學們滿意的菜餚。當然,不同的人口味也不一定相同,但每個人的口味都可以用乙個非負整數表示。由於人手不夠,食堂每次只能為乙個人做菜。做每道菜所需的時間是和前一道菜有關的,若前一道菜的對應的口味是a...
SDOI2009 學校食堂
小f 的學校在城市的乙個偏僻角落,所有學生都只好在學校吃飯。學校有乙個食堂,雖然簡陋,但食堂大廚總能做出讓同學們滿意的菜餚。當然,不同的人口味也不一定相同,但每個人的口味都可以用乙個非負整數表示。由於人手不夠,食堂每次只能為乙個人做菜。做每道菜所需的時間是和前一道菜有關的,若前一道菜的對應的口味是a...