bzoj 1226 学校食堂
時間限制:1秒 內存限制:64M
【問題描述】
小F的學校在城市的一個偏僻的角落,所有學生只好在學校食堂吃飯。學校有一個食堂,雖然簡陋,但食堂大廚總能做出讓同學滿意的菜肴。當然,不同的人的口味也不一定相同,但每個人的口味都可以用一個非負整數表示。
由于人手不夠,食堂在同一時間只能為一個人做菜。每道菜所需時間是和前一道菜有關的,若前一道菜對應的口味是a,這一道為b,則做這道菜所需要的時間為(a or b)-(a and b),而做第一道菜是不需要計算時間的。其中or和and表示整數逐位或運算及逐位與運算,C語言中對應的運算符為“|”和“&”。
學生數目相對還是比較多的,吃飯做菜往往會花去大量時間。因此,學校食堂偶爾會不按照大家的排隊順序做菜,以縮短總的進餐時間。
雖然同學們能夠理解學校食堂的這種做法,不過每個同學還是有一定的容忍度的。也就是說,隊伍中的第i個同學,最多允許緊跟其后的Bi個人先拿飯菜。一旦在此之后的任意同學比當前同學先拿到飯菜,當前同學會十分憤怒。因此食堂做菜還是要照顧到同學們的情緒。
現在小F想知道在滿足所有人容忍度的這一前提下,學校食堂做完所有菜需要最少時間。
【輸入格式】
第一行一個整數C,表示測試點的數據組數。每組數據的第一行是一個整數N,表示學生數量。接下來的N行,每行包含兩個整數:Ti和Bi,表示隊伍按順序從前向后的每個學生的所需菜的口味和這個學生的容忍度。
【輸出格式】
包含C行,每行一個整數,表示對應數據中食堂完成所有菜所需要的時間。
【輸入樣例】
2
5
5 2
4 1
12 0
3 3
2 2
2
5 0
4 0
【輸出樣例】
16
1
【樣例解釋】
對于第1組數據,一種最優秀的做菜方案是:3,2,1,4,5,每道菜所須時間為:0,8,1,6,1
【數據范圍】
30%的數據,滿足1<=N<=20
100%的數據,滿足1<=N<=1000,0<=Ti<=1000,0<=Bi<=7,1<=C<=5
存在30%的數據,滿足0<=Bi<=1。
存在65%的數據,滿足0<=Bi<=5。
存在45%的數據,滿足0<=Ti<=130。
【來源】
bzoj 1226
這道題是排隊問題的加強版,但思路還是一樣的,K排隊問題
我們依舊按照排隊問題的方法設置數組,但要加一維來表示最后一個人是誰。
d[i][j][A]:前i-1個人已經吃了,最后一個人是i+j,{i,i+1,…..,i+8}個人中吃了的人的集合。
遞推的思路還是和排隊問題一樣。
代碼如下:
#include<cstdlib> #include<cstdio> #include<cstring> #include<iostream> using namespace std; typedef long long ll; const int maxn=1005; const ll inf=2000000000005ll;int n,all,c[maxn],a[maxn]; ll d[maxn][20][1<<8],b[20],w[maxn][maxn];void init() {scanf("%d",&n);for(int i=0;i<=n+1;i++)for(int j=0;j<=16;j++)for(int k=0;k<=all;k++) d[i][j][k]=inf;for(int i=1;i<=n;i++) scanf("%d%d",&a[i],&c[i]);for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)w[i][j]=(a[i]|a[j])-(a[i]&a[j]);int tt;d[1][7][0]=0;for(int i=1;i<=n;i++){for(int t=0;t<=all;t++)for(int j=0;j<=16;j++) if(d[i][j][t]!=inf){if(t&1) d[i+1][j-1][t/2]=min(d[i+1][j-1][t/2],d[i][j][t]);else{tt=n;for(int k=0;k<=7;k++) if(!(b[k]&t)){if(i+k>tt) break;tt=min(tt,i+k+c[i+k]);d[i][8+k][t+b[k]]=min(d[i][8+k][t+b[k]],d[i][j][t]+w[i+j-8][i+k]);}}}} } int main() {//freopen("in.txt","r",stdin);//freopen("out.txt","w",stdout);b[0]=1;for(int i=1;i<=11;i++) b[i]=b[i-1]<<1;all=b[8]-1;int T;scanf("%d",&T);while(T--){init();ll ans=inf;for(int i=0;i<=16;i++) ans=min(ans,d[n+1][i][0]);cout<<ans<<endl;}return 0; }總結
以上是生活随笔為你收集整理的bzoj 1226 学校食堂的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 23届应届毕业生秋招分享——秋招经验
- 下一篇: 计算机考研考的是英语作文,2007年考研