18430 Aerial Photography
该题有题解
时间限制:1000MS 内存限制:65535K
提交次数:48 通过次数:9
题型: 编程题 语言: 不限定
Description
Alice is preparing for her next trip during the summer vocation. She is now planing for the route of aerial photography (taking photos with drones).
She will launch the drone on a certain place, for convenience, we consider it point (0, 0), and she wants to take photos in several places near the
origin point. A drone can only fly at most M kilometers continually with a fully charged batteries, or it will crash due to lack of electricity. So, Alice
will repeat switching batteries for the drone during each launch.
As there aren’t any chagers outside, she can’t charge batteries during the flight. She must buy enough batteries before her trip. So please tell Alice
how many batteries at least she should take to fly to every places on her plan.
输入格式
The first line is a number T, indicating the number of test cases.
For each case, the first line contains two integers N and M, separated by one space, indicating the number of destinations for taking photos and
the maximum flight distance for a fully charged battery. Then followed by N lines, each line contains two integers – the coordination of a destination
point. Specially, the destinations will not contains (0, 0).
It is guaranteed that the distance between (0, 0) and any destinations will not exceed M/2.
Restrictions: 0 <= T <= 20, 0 <= N < 10, 0 < M <= 1e9.
输出格式
For each case, output the case number and followed by the minimun count of batteries she should take.
输入样例
1
3 20
3 4
0 10
4 -3
输出样例
2
标签:dp,暴力。按着dp的思路我几天都没有想出来。
今早突然想到这到题,好像可以深搜,想了一下n如果是10,复杂度有点高,一看题,n<=9,狂喜,写了30分钟通过了。
行数:43. 时间:899ms(好险)
先预处理每两个点之间的距离。然后就可以深搜啦。
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
using namespace std;
int n,m,mapp[15][2],ans,v[15];
double d[12][12];
void dfs(int now,int sum,int dis,int flag)///变量代表当前位置,已用电池,当前走过的距离,走过的点数。
{
if(flag>=n){if(dis!=0)ans=min(ans,sum+1);else ans=min(ans,sum);return ;} ///当点数flag够了,如果当前在原点,ans和sum比较,如果不再原点,ans和sum+1比较
if(sum>ans)return ;
for(int i=1;i<=n;++i){
if(!v[i]&&dis+d[now][i]+d[0][i]<=m){ ///能飞过去并且还能飞回原点。
v[i]=1;
dfs(i,sum,dis+d[now][i],flag+1);
v[i]=0;
}
}
dfs(0,sum+1,0,flag); ///没有能飞的点,直接飞回原点,电池加一。
int main()
{
int i,j,k,l,T;
cin >> T ;
while(T--){
memset(mapp,0,sizeof(mapp));
memset(d,0,sizeof(d));
memset(v,0,sizeof(v));
ans=1e9;
scanf("%d%d",&n,&m);
for(i=1;i<=n;++i){
scanf("%d%d",&mapp[i][0],&mapp[i][1]);
}
for(i=0;i<=n;++i) ///预处理两点之间的距离。
for(j=i+1;j<=n;++j)
if(i!=j)d[i][j]=d[j][i]=(double)sqrt(pow(mapp[i][0]-mapp[j][0],2)+pow(mapp[i][1]-mapp[j][1],2));
dfs(0,0,0,0);
cout << ans << endl ;
}
return 0;
}