重温世界杯
Description
世界杯结束了,意大利人连本带利的收回了法国人6年前欠他们的债,捧起了大力神杯,成就了4星意大利.
世界杯虽然结束了,但是这界世界杯给我们还是留下许多值得回忆的东西.比如我们听到了黄名嘴的3分钟激情解说,我们懂得了原来可以向同一个人出示3张黄牌,我们还看到了齐达内的头不仅能顶球还能顶人…………
介于有这么多的精彩,xhd决定重温德国世界杯,当然只是去各个承办世界杯比赛的城市走走看看.但是这需要一大比钱,幸运的是xhd对世界杯的热爱之情打动了德国世界杯组委会,他们将提供xhd在中国杭州和德国任意世界杯承办城市的往返机票,并说服了这些城市在xhd到达这座城市时为他提供一笔生活费以便他在那里参观时用,当参观完时剩余的钱也将留给xhd,但当生活费不够时他们将强行结束xhd的这次德国之行,除了这个,他们还有一个条件,xhd只能根据他们所给的路线参观.比如有3座城市a,b,c,他们给定了a-b-c-a的路线,那么xhd只有3种参观顺序abc,bca,cab.由于各个城市所提供的生活费和在那里的花费都不同,这使xhd很头痛,还好我们事先知道了这笔生活费和花费.请问xhd最多能顺利参观几座城市?
世界杯虽然结束了,但是这界世界杯给我们还是留下许多值得回忆的东西.比如我们听到了黄名嘴的3分钟激情解说,我们懂得了原来可以向同一个人出示3张黄牌,我们还看到了齐达内的头不仅能顶球还能顶人…………
介于有这么多的精彩,xhd决定重温德国世界杯,当然只是去各个承办世界杯比赛的城市走走看看.但是这需要一大比钱,幸运的是xhd对世界杯的热爱之情打动了德国世界杯组委会,他们将提供xhd在中国杭州和德国任意世界杯承办城市的往返机票,并说服了这些城市在xhd到达这座城市时为他提供一笔生活费以便他在那里参观时用,当参观完时剩余的钱也将留给xhd,但当生活费不够时他们将强行结束xhd的这次德国之行,除了这个,他们还有一个条件,xhd只能根据他们所给的路线参观.比如有3座城市a,b,c,他们给定了a-b-c-a的路线,那么xhd只有3种参观顺序abc,bca,cab.由于各个城市所提供的生活费和在那里的花费都不同,这使xhd很头痛,还好我们事先知道了这笔生活费和花费.请问xhd最多能顺利参观几座城市?
Input
每组输入数据分两行,第一行是一个正整数n(1<=n<=100000),表示有n座城市.接下来的一行按照给定的路线顺序的输出这n个城市的生活费和花费,w1,l1,w2,l2,……,wn,ln,其中wi,li分别表示第i个城市的生活费和花费,并且它们都是正整数.
Output
对应每组数据输出最多能参观的城市数.
Sample Input
3 3 2 3 4 2 2 3 3 2 3 4 2 3
Sample Output
3 2收获:本应该用dp写的,但是我看不懂dp的方式,只好用土方法写,从第一个城市开始走,走到钱变成负时,判断max和sum的大小,后将sum至零,然后从下一个城市开始继续走,当从最后一个城市进入第一个城市后,再碰到负的话就不用继续走了,肯定没有之前的多了。其实就是最长序列,下次找个机会看看dp的算法。include<iostream> #include <cstdio> using namespace std; int get[100001]; int cost[100001]; int vis[100001]; int main(){ int i,j,sum,a,n,s,e,m,max; while(scanf("%d",&n)!=EOF) { for(i=0;i<=n-1;i++) { cin>>get[i]>>cost[i]; } s=e=m=sum=max=0; while(1) { a=m+get[e]-cost[e]; if(a<0) { if(s>e) { max=sum>max?sum:max; break;} else { if(s==n-1) { max=sum;break;} s=(e+1); e=s; max=sum>max?sum:max; sum=m=0; } } else { if(s==(e+1)%n) { max=n;break;} sum=sum+1; e=(e+1)%n; m=a; } } printf("%d\n",max); } }
鉴于自己正做的赛题是求有条件的最短路,故特地找到这题
这题的限制是要在一定的花费内走最短路
华为挑战赛的条限制是要走过特定的点
应该差不多
准备尝试多种方法
1.小优的DFS加剪枝
剪枝技巧:
建立邻接表而不是邻接矩阵,因为边太多,而且有重边,矩阵是不可以的
当前城市为n时,判断最小值
若下一个城市已走过,则不走
若当前花费大于限制k,不往下走
若当前路程小于已知的最小值,不往下走
#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
#define Road_M 10005
#define City_M 105
#define INF 9999999
struct
{
int s,d,l,t;
int next;
}road[Road_M];
int Head[City_M],vis[City_M];
int min_dis,k,n;
void dfs(int now_city,int cost,int now_dis)
{
int i,ll,dd,tt;
if(cost>k||now_dis>min_dis)
return ;
if(now_city==n)
{
if(now_dis<min_dis)
min_dis=now_dis;
return ;
}
for(i=Head[now_city];i!=-1;i=road[i].next)
{
dd=road[i].d;
ll=road[i].l;
tt=road[i].t;
if(vis[dd]==1)
continue;
else vis[dd]=1;
dfs(dd,cost+tt,now_dis+ll);
vis[dd]=0;
}
}
int main(void)
{
int r,i,ss,dd,ll,tt;
scanf("%d%d%d",&k,&n,&r);
memset(Head,-1,sizeof(Head));
memset(vis,0,sizeof(vis));
for(i=0;i<r;i++)
{
scanf("%d%d%d%d",&ss,&dd,&ll,&tt);
road[i].s=ss;
road[i].d=dd;
road[i].l=ll;
road[i].t=tt;
road[i].next=Head[ss];
Head[ss]=i;
}
min_dis=INF;
vis[1]=0;
dfs(1,0,0);
if(min_dis!=100000)
printf("%d\n",min_dis);
else printf("-1\n");
return 0;
}
2.
优先队列+BFS
以BFS的形式搜, 优先出路程短或者花费少的,这样第一次遇到终点时,便是答案
#include<iostream>
#include<algorithm>
#include<cmath>
#include <queue>
using namespace std;
#define Road_M 10005
#define City_M 105
#define INF 9999999
struct
{
int s,d,l,t;
int next;
}road[Road_M];
int Head[City_M],vis[City_M];
int min_dis,k,n;
struct State
{
int now_city,cost,road_len; //最先出队的为最大的
bool operator < (const struct State a)const
{
if(a.road_len==road_len)
return a.cost<cost;
return a.road_len<road_len;
}
};
void bfs()
{
priority_queue<State>q;
State sta;
min_dis=INF;
int i,e,d,nc,c;
while(!q.empty())
q.pop();
sta.road_len=0;
sta.now_city=1;
sta.cost=0;
q.push(sta);
while(!q.empty())
{
State x,y;
x=q.top();q.pop();
nc=x.now_city;
if(nc==n)
{
min_dis=x.road_len;
break;
}
for(i=Head[nc];i!=-1;i=road[i].next)
{
c=road[i].t;
d=road[i].l;
e=road[i].d;
if(x.cost+c<=k)
{
y.cost=x.cost+c;
y.now_city=e;
y.road_len=x.road_len+d;
q.push(y);
}
}
}
}
int main(void)
{
int r,i,ss,dd,ll,tt;
scanf("%d%d%d",&k,&n,&r);
memset(Head,-1,sizeof(Head));
memset(vis,0,sizeof(vis));
for(i=0;i<r;i++)
{
scanf("%d%d%d%d",&ss,&dd,&ll,&tt);
road[i].s=ss;
road[i].d=dd;
road[i].l=ll;
road[i].t=tt;
road[i].next=Head[ss];
Head[ss]=i;
}
bfs();
return 0;
}