最近由於想鍛鍊小型程式編寫能力,所以打算做完usaco,當然這個是比較水的題目,但對於業餘acm愛好
者的我來說還是有一定難度的,拿來練手和學習還是很不錯的。
mother』s milk是乙個搜尋的題目,總的來說難度不大,但是我在一開始的時候並沒有那麼輕易的看出狀
態的轉移方式,在狀態轉移那裡卡了很久,一直在想怎麼模擬這個倒水的過程?其實我是陷入題目的誤
區,明知道是到搜尋題目,就應該以搜尋的方式來思考,那麼怎麼思考搜尋題目的解法呢?
首先,搜尋的題目最重要的就是找到狀態,就是怎麼樣乙個東西算作此題的狀態,亦即解空間的乙個節
點,這是首要任務,如果連狀態都沒定義好,後續的一切都是浮雲。
然後呢,就是要思考從乙個狀態有幾種轉移方式,就是從解空間的乙個節點出發有條邊和其他節點相連,
這樣就能夠大概估計到解空間的大小,以考慮是用深搜呢,還是廣搜。如果空間需求不大,解可能在離根節
點較近的地方,就果斷廣搜,其他就深搜吧。我廣搜一般是用佇列,深搜是用遞迴實現的,這中間要考慮幾點:
因此果斷剪掉3次以上同型別旋轉)
最後就是編碼實現了,然後考慮各種優化問題,例如查詢改成雜湊等等。
用這種想法思考mother』s milk, 考慮到狀態就是 (a桶中牛奶的數量,b桶中牛奶的數量),因為牛奶的
總數量是確定的,所以上述序列足可確定乙個解空間的節點。然後思考可以有幾種轉移方式?很明顯,總共
三個桶,因此就是6種:a->b a->c b->a b->c c->a c->b。以a->b來說,這樣轉移之後狀態是什麼呢?a的
牛奶數應該是max(0, a+b-b),其中a,b是a和b桶中原來牛奶的數量,a,b是a和b桶的容量。b的牛奶數是
min(a+b, b),其他的以此類推。
估算一下解空間的大小吧,由於題目限制a,b,c的值是1-20之間,所以總共的狀態,最多,也就
20*20=400,所以,用廣搜就行。**如下:
1: /*
3: prog:milk3
4: lang:c++
5: */
6:
7: #include
8: #include
9: #include
10: #include
11: #include
12: #include
13: #include
14: #include
15:
16: usingnamespace std;
17:
18: struct state
19: ;
24:
25: constint num=21;
26: bool bflag[num][num];//判重
27:
28: //廣搜
29: //pre: 輸入a,b,c是 桶的容量
30: //post: 輸出res,是 c的可能數,未排序
31: void getanswer(int a, int b, int c, vector& res)
32:
51: bflag[s.a][s.b]=true;
52: //all 6 possibilities
53:
54: state temp = s;
55: //1 a->b
56: s.a = max(0,s.a+s.b-b);
57: s.b = min(temp.a+s.b,b);
58: if(!bflag[s.a][s.b])
59: q.push(s);
60: s=temp;
61:
62: //2 a->c
63: s.a = max(0,s.a+s.c-c);
64: s.c = min(temp.a+s.c,c);
65: if(!bflag[s.a][s.b])
66: q.push(s);
67: s=temp;
68:
69: //3 b->a
70: s.b = max(0,s.b+s.a-a);
71: s.a = min(temp.b+s.a,a);
72: if(!bflag[s.a][s.b])
73: q.push(s);
74: s=temp;
75:
76: //4 b->c
77: s.b = max(0,s.b+s.c-c);
78: s.c = min(temp.b+s.c,c);
79: if(!bflag[s.a][s.b])
80: q.push(s);
81: s=temp;
82:
83: //5 c->b
84: s.c = max(0,s.c+s.b-b);
85: s.b = min(temp.c+s.b,b);
86: if(!bflag[s.a][s.b])
87: q.push(s);
88: s=temp;
89:
90: //6 c->a
91: s.c = max(0,s.c+s.a-a);
92: s.a = min(temp.c+s.a,a);
93: if(!bflag[s.a][s.b])
94: q.push(s);
95: s=temp;
96: }
97: }
98: }
99:
100: int main(void)
101:
117:
118: vector res;
119:
120: getanswer(a,b,c,res);
121:
122: sort(res.begin(),res.end());
123: for(vector::iterator it=res.begin(); it!=res.end()-1; it++)
124:
127:
128: fout/*USACO 修理牛棚
同樣是一道貪心題,我的思路是用乙個陣列存下所有的空擋,對空擋進行排序,然後再在總長度中減去前m 1 大的空檔長度。關鍵還是理解題意。貌似洛谷 oj不支援 int min 之類的。還有要對初始資料排一次序,害我 wa了一次。include include includeusing namespace ...
USACO 奶牛電信
題目鏈結 洛谷1345 題目大意 給出乙個 n 個點 m條邊的無向圖,與 s,t 問至少刪去多少個點,使 s,t 不連通。n 100,m 600 分析 1.對於這種分離s,t 的題,考慮最大流 最小割的方法。2.然而題目要求割點,而不是割邊,怎麼辦?這就是一種經典的拆點題。3.把每個點 i 拆成兩個...
USACO混合牛奶
題目 問題 a 混合牛奶 時間限制 1 sec 記憶體限制 128 mb 提交 39 解決 25 提交 狀態 討論版 命題人 201805050252 題目描述 牛奶包裝是乙個如此低利潤的生意,所以盡可能低的控制初級產品 牛奶 的 變的十分重要。請幫助快樂的牛奶製造者 merry milk make...