SDOI2009 學校食堂(狀壓dp)

2022-05-04 09:18:06 字數 1190 閱讀 4133

我擦。。。有毒吧。。好久沒調**調過這麼久了。。。

題目的難點就在於每個人打飯的順序不是一定的 這點特別阻礙思想

注意到乙個人的容忍度最多為7 聯想到狀壓

考慮dp陣列的定義

首先我們可以把乙個人及其後面的7人打沒打飯的狀態壓縮 

其次肯定要記錄當前到打飯到哪個人了(即1~i-1都打完了飯)

但是似乎少了點啥 對於更新式子(a or b)-(a and b) 我們雖然可以列舉出b 但是a是不知道的

那就記錄一下a是哪個嘛。。反正對於已經打完飯的人們 他們打飯的順序我們不關心

不過直接記錄會炸 最終我們的dp方程的定義就是:

設f[i][j][k]表示第1個人到第i-1個人已經打完飯,第i個人以及後面7個人是否打飯的狀態為j,k表示目前為止最後乙個打飯的人離i的相對位置 ,所用的時間

那麼列舉i,j,k,

如果j&1為1 就是第i個人買了飯 於是可以把j右移1 再更新等效的f(i+1,(j>>1),k-1)

如果為0 列舉後面七個人哪個買 只要大家都能容忍他 就可以更新了

另外 (a or b)-(a and b)其實就是a xor b.....,由於k有可能是負數,所以巨集定義一下,具體見**

#include//

設f[i][j][k]表示第1個人到第i-1個人已經打完飯

//第i個人以及後面7個人是否打飯的狀態為j,k表示目前為止最後乙個打飯的人離i的相對位置 所用的時間

#define n 1005

#define inf 0x3f3f3f3f

#define f(i,j,k) dp[i][j][k+8]

using

namespace

std;

intn,t[n],b[n];

int dp[n][(1

<<8)+15][20

];inline

int calc(int x,int

y)int

main()}}

}}}}

int ans=inf;

for(int k=-8;k<=7;k++)

ans=min(ans,f(n+1,0

,k));

cout

}return0;

}

SDOI2009 學校食堂

time limits 1000 ms memory limits 262144 kb detailed limits description 小f 的學校在城市的乙個偏僻角落,所有學生都只好在學校吃飯。學校有乙個食堂,雖然簡陋,但食堂大廚總能做出讓同學們滿意的菜餚。當然,不同的人口味也不一定相同,...

SDOI2009 學校食堂

這道題的思想是 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...

SDOI2009 學校食堂

小f 的學校在城市的乙個偏僻角落,所有學生都只好在學校吃飯。學校有乙個食堂,雖然簡陋,但食堂大廚總能做出讓同學們滿意的菜餚。當然,不同的人口味也不一定相同,但每個人的口味都可以用乙個非負整數表示。由於人手不夠,食堂每次只能為乙個人做菜。做每道菜所需的時間是和前一道菜有關的,若前一道菜的對應的口味是a...