UVA - 10603 Fill(隱式圖搜索)
阿新 • • 發佈:2017-07-22
split contain append 經典的 string proc 剛才 ems i++
題目大意:經典的倒水問題。
給你三個瓶子,體積為a,b,c。
剛開始a。b是空的,c是滿的,如今要求你到出體積為d的水。倒水的規則為,要麽倒水方為空,要麽接水方滿
問倒到容量為d時,倒水的最小體積是多少。假設不能倒出體積為d的水,找出d’ < d,最接近d的d’和最小的體積
解題思路:剛才時以為直接bfs,用vis標記一下就結束了,結果WA了。為什麽會WA。由於我這樣求的是倒水次數最少的,而不是倒水體積最小的,WA是肯定的了
接著將vis數組改成int型的,紀錄達到這個狀態時倒水的體積。結果可想而之TLE(可能是我寫搓了。。)
借鑒了一下別人的,恍然大悟,用一個數組代表倒出這個體積的水時倒的水的最小體積,這樣就能夠降低非常多種情況了,確實是一個大剪枝
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
#define N 210
#define INF 0x3f3f3f3f
struct Node{
int have[3];
int d;
}n1, n2;
int done[N], val[3];
int d;
bool vis[N][N];
void init() {
memset(vis, 0, sizeof(vis));
memset(done, 0x3f, sizeof (done));
scanf("%d%d%d%d", &val[0], &val[1], &val[2], &d);
done[0] = done[val[2]] = 0;
}
void bfs() {
queue<Node> Q;
vis[0][0] = true;
n1.have[0] = n1.have[1] = n1.d = 0;
n1.have[2] = val[2];
Q.push(n1);
while (!Q.empty()) {
n1 = Q.front();
Q.pop();
for (int i = 0; i < 3; i++)
for (int j = 0; j < 3; j++) {
if (i ^ j) {
n2 = n1;
int tmp = val[j] - n2.have[j] < n2.have[i] ? val[j] - n2.have[j] : n2.have[i];
n2.have[j] += tmp;
n2.have[i] -= tmp;
n2.d += tmp;
if (!vis[n2.have[0]][n2.have[1]] || done[n2.have[0]] > n2.d || done[n2.have[1]] > n2.d || done[n2.have[2]] > n2.d) {
vis[n2.have[0]][n2.have[1]] = true;
for (int k = 0; k < 3; k++) {
done[n2.have[k]] = min(done[n2.have[k]], n2.d);
}
Q.push(n2);
}
}
}
}
}
void solve() {
bfs();
for (int i = d; i >= 0; i--)
if (done[i] != INF) {
printf("%d %d\n", done[i], i);
break;
}
}
int main() {
int test;
scanf("%d", &test);
while (test--) {
init();
solve();
}
return 0;
}
UVA - 10603 Fill(隱式圖搜索)