题目链接
题目大意
把捷运淡水线想像成一个数轴,共有 m 个捷运站,第 i 个捷运站的座标为 xi ,任两个捷运站的座标都不相同。dreamoon 某天搭了 n 次捷运的过程可由一个序列 ai表示, a1为起点站,过程中 dreamoon 共搭乘了 n 次捷运,第i 次是由第 di 站搭到第 di+1 站。dreamoon 可能经过同一站好多次,且起点站不一定要和终点站相同,也就是 d1 不一定和 dn+1 相等。 现在给你n 个数 di, 为 dreamoon 第 i 次搭乘捷运时捷运移动的距离 (也就是.|xai + 1 - xai| ),但你不知道序列 是什么,也不知道每个捷运站的座标,请根据这些信息推算淡水捷运站至少有几站。
解题思路
我们不妨设第一个捷运站在0的位置,每次dreamoon可以向正方向移动,也可以向负方向移动,那么我们就用dfs模拟这个过程,vis[]记录这个坐标上建捷运站的话经过了几次,如果是第一个经过也就是vis==1的时候,表示新经过了一个捷运站,捷运站总数要加一。
为了不出现负数,我们假设第一个捷运站的位置在2500000的位置上,这样加加减减中就不会出现负数比较好记录。
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
const int N=25,M=100000;
int n;
int a[100005],vis[5000100],ans;
void dfs(int i,int res,int v)
{
if(i>n)
{
ans=min(ans,v);
return ;
}
//向正方向移动
vis[res+a[i]]++;
dfs(i+1,res+a[i],v+(vis[res+a[i]]==1));//当vis=1时说明多加了一个捷运站
vis[res+a[i]]--;
//向负方向移动
vis[res-a[i]]++;
dfs(i+1,res-a[i],v+(vis[res-a[i]]==1));
vis[res-a[i]]--;
}
int main()
{
ans=25;
memset(vis,0,sizeof(vis));
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
vis[N*M]=1;//假设第一个捷运站的位置在250000
dfs(1,N*M,1);
printf("%d\n",ans);
return 0;
}