#POJ2331#Water pipe(IDA*_搜索)

来源:互联网 发布:macsd卡恢复软件 编辑:程序博客网 时间:2024/05/28 06:04

Water pipe
Time Limit: 3000MS Memory Limit: 65536KTotal Submissions: 2508 Accepted: 715

Description

The Eastowner city is perpetually haunted with water supply shortages, so in order to remedy this problem a new water-pipe has been built. Builders started the pipe from both ends simultaneously, and after some hard work both halves were connected. Well, almost. First half of pipe ended at a point (x1, y1), and the second half -- at (x2, y2). Unfortunately only few pipe segments of different length were left. Moreover, due to the peculiarities of local technology the pipes can only be put in either north-south or east-west direction, and be connected to form a straight line or 90 degree turn. You program must, given L1, L2, ... Lk -- lengths of pipe segments available and C1, C2, ... Ck -- number of segments of each length, construct a water pipe connecting given points, or declare that it is impossible. Program must output the minimum required number of segments. 

Constraints 
1 <= k <= 4, 1 <= xi, yi, Li <= 1000, 1 <= Ci <= 10

Input

Input contains integers x1 y1 x2 y2 k followed by 2k integers L1 L2 ... Lk C1 C2 ... Ck

Output

Output must contain a single integer -- the number of required segments, or −1 if the connection is impossible.

Sample Input

20 10 60 50 2 70 30 2 2

Sample Output

4

题意:

给出K种长度的水管,并告诉每种长度有多少根,要求用这些水管从(x1,y1)一直铺到(x2,y2),最少使用多少根水管,水管可以交叉。

注意水管铺的范围坐标在0 ~ 1000


剪枝很重要,H值得设置如下:

假设现在只考虑一个坐标,那么BFS计算出可能到达的所有单个坐标的最少管道数量,

而对于当前的点x,y,它到达终点的管道数量,一定能保证大于等于Bfs单座标数+当前数,


Code:

StatusAcceptedTime641msMemory744kBLength2111LangG++Submitted2017-10-06 16:45:14Shared

#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>#include<queue>#include<algorithm>using namespace std;const int Max = 6;bool flg;int K, lim, sum;int x1, y1, x2, y2;int L[Max], C[Max], H1[1005], H2[1005];int dd[4][2] = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};void getint(int & num){    char c; int flg = 1;    num = 0;    while((c = getchar()) < '0' || c > '9') if(c == '-')    flg = -1;    while(c >= '0' && c <= '9'){    num = num * 10 + c - 48;    c = getchar(); }    num *= flg;}int Bfs_H(int * H, int s){    queue<int>Q;    H[s] = 0;    Q.push(s);    while(! Q.empty()){        int tmp = Q.front();    Q.pop();        for(int i = 1; i <= K; ++ i){            int x = tmp - L[i];            if(x > 0 && H[x] == -1)                H[x] = H[tmp] + 1,                Q.push(x);            x += (L[i] << 1);            if(x <= 1000 && H[x] == -1)                H[x] = H[tmp] + 1,                Q.push(x);        }    }}void Dfs(int x, int y, int now, int *state){    if(now > lim)   return ;    if(x == x2 && y == y2){flg = 1; return ;}    if(now + H1[x] > lim || now + H2[y] > lim) return ;    int newstate[Max];    memcpy(newstate, state, sizeof newstate);    for(int i = 1; i <= K; ++ i)    if(newstate[i]){        -- newstate[i];        for(int j = 0; j < 4; ++ j){            int xx = x + L[i] * dd[j][0];            int yy = y + L[i] * dd[j][1];            if(xx >= 0 && yy >= 0 && xx <= 1000 && yy <= 1000)                Dfs(xx, yy, now + 1, newstate);            if(flg) return ;        }        ++ newstate[i];    }}int main(){    getint(x1), getint(y1), getint(x2), getint(y2);    getint(K);    for(int i = 1; i <= K; ++ i)    getint(L[i]);    for(int i = 1; i <= K; ++ i)    getint(C[i]), sum += C[i];    if(x1 == x2 && y1 == y2){puts("0"); return 0;}    memset(H1, -1, sizeof H1 );    memset(H2, -1, sizeof H2 );    Bfs_H(H1, x2);    Bfs_H(H2, y2);    for(lim = 1; lim <= sum; ++ lim){        Dfs(x1, y1, 0, C);        if(flg) break;    }    if(flg) printf("%d\n", lim);    else puts("-1");    return 0;}









原创粉丝点击