USACO 從Mother s Milk看搜尋

2022-05-06 22:30:07 字數 3432 閱讀 2093

最近由於想鍛鍊小型程式編寫能力,所以打算做完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: using

namespace std;

17:
18: struct state
19: ;
24:
25: const

int 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...