我擦。。。有毒吧。。好久沒調**調過這麼久了。。。
題目的難點就在於每個人打飯的順序不是一定的 這點特別阻礙思想
注意到乙個人的容忍度最多為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...