题意是这样的:
有一堆管子,长度为k,数量为n,然后起点为x1,y1,终点为x2,y2,管道只能水平、垂直放置,问最少需要的管子数量。如果不可能,输出-1
这题由于状态太大,采取一般的BFS肯定要爆时间,所以,还是用IDA*。首先,观察到x方向和y方向可以独立来处理,下限函数可以取为没有数量限制时从a到b需要的最少管道数,这个可以通过BFS来解决,复杂度为O(n)。
不多说,贴代码
1
Source Code
2
# include <cstdio>
3
# include <cstring>
4
# include <queue>
5
using namespace std;
6
int c[5],l[5],n,res=0xfffffff;
7
int x1,y1,x2,y2;
8
int referx[1001],refery[1001];
9
queue<int> q;
10
bool solve(int pos,int len,bool type)
11![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif)
{
12
if(!type)
13![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
14
if(referx[pos]==-1||len+referx[pos]>res) return false;
15
if(pos==x2)
16![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
17
return solve(y1,len,1);
18
}
19
for(int i=1;i<=n;i++)
20
if(c[i])
21![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
22
if(x2<pos)
23![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
24
if(pos-l[i]>=1)
25![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
26
c[i]--;
27
if(solve(pos-l[i],len+1,0)) return true;;
28
c[i]++;
29
}
30
if(pos+l[i]<=1000)
31![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
32
c[i]--;
33
if(solve(pos+l[i],len+1,0)) return true;
34
c[i]++;
35
}
36
}
37
else
38![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
39
if(pos+l[i]<=1000)
40![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
41
c[i]--;
42
if(solve(pos+l[i],len+1,0)) return true;
43
c[i]++;
44
}
45
if(pos-l[i]>=1)
46![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
47
c[i]--;
48
if(solve(pos-l[i],len+1,0)) return true;;
49
c[i]++;
50
}
51
}
52
}
53
}
54
else
55![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
56
if(refery[pos]==-1||len+refery[pos]>res) return false;
57
if(pos==y2)
58![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
59
return true;
60
}
61
for(int i=1;i<=n;i++)
62
if(c[i])
63![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
64
if(y2<pos)
65![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
66
if(pos-l[i]>=1)
67![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
68
c[i]--;
69
if(solve(pos-l[i],len+1,1)) return true;
70
c[i]++;
71
}
72
if(pos+l[i]<=1000)
73![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
74
c[i]--;
75
if(solve(pos+l[i],len+1,1)) return true;
76
c[i]++;
77
}
78
}
79
else
80![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
81
if(pos+l[i]<=1000)
82![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
83
c[i]--;
84
if(solve(pos+l[i],len+1,1)) return true;
85
c[i]++;
86
}
87
if(pos-l[i]>=1)
88![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
89
c[i]--;
90
if(solve(pos-l[i],len+1,1)) return true;
91
c[i]++;
92
}
93
}
94
}
95
}
96
return false;
97
}
98
void cal(int refer[],int pos)
99![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif)
{
100
refer[pos]=0;
101
q.push(pos);
102
while(!q.empty())
103![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
104
pos=q.front();
105
q.pop();
106
for(int i=1;i<=n;i++)
107![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
108
if(pos-l[i]>=1&&refer[pos-l[i]]==-1)
109![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
110
refer[pos-l[i]]=refer[pos]+1;
111
q.push(pos-l[i]);
112
}
113
if(pos+l[i]<=1000&&refer[pos+l[i]]==-1)
114![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
115
refer[pos+l[i]]=refer[pos]+1;
116
q.push(pos+l[i]);
117
}
118
}
119
}
120
}
121
int main()
122![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif)
{
123
int total=0;
124
scanf("%d%d%d%d%d",&x1,&y1,&x2,&y2,&n);
125
for(int i=1;i<=n;i++)
126
scanf("%d",l+i);
127
for(int i=1;i<=n;i++)
128![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
129
scanf("%d",c+i);
130
total+=c[i];
131
}
132
memset(referx,-1,sizeof(referx));
133
memset(refery,-1,sizeof(refery));
134
cal(referx,x2);
135
cal(refery,y2);
136
for(res=0;res<=total;res++)
137
if(solve(x1,0,0)) break;
138
if(res==total+1) printf("-1\n");
139
else printf("%d\n",res);
140
// system("pause");
141
return 0;
142
}
143![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
144![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)