您的位置:首页 > 其它

UVA301回溯法求坐火车问题的最大收益

2015-09-25 16:32 253 查看
这题站点最大为七,订单数为22,然后一开始就想着去按站点去进行搜索,然后写了n久,写不对,写残了,然后就去搜订单。

当时脑子乱了,去随便去写搜索搜订单,最后写好交上去连着T了4发,最后稍微改了下竟然以2666ms的时间险过了,然后看了

看别人交的时间,再没有比我的时间长的了,而且竟然还有一个19ms过的,实在很想看看别人19ms是怎么过的,然而别人的

代码不开放,没办法了,但比我的时间少的代码还是有很多的,另外当时我脑子乱了,其实简化时间的方法很简单,开个数组

存储经过每个站点的人数,注意是人数,最后这些人数加起来就是总价格,应该很好理解,其次在搜索的过程中,只要每个站点的

人数都不会超出容量就可以了,最后记得递归之后要还原数组。下面先贴一发我的神奇的2666ms过的代码,后面再贴一发简化时间后

的代码,其实简化时间的代码有些类似子集枚举的位向量法:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<string>
#include<algorithm>
#include<map>
#include<set>
#include<vector>
#include<stack>
#include<queue>
#include<climits>
#define LL long long
using namespace std;
int n,m,q;
struct node
{
int bs,ds,ps;
int se;
};
int flag[30];
node orr[30];
int ans;
bool work()
{
int sum[10];
memset(sum,0,sizeof(sum));
for(int i=0;i<q;i++)
if(flag[i])
{
for(int j=orr[i].bs;j<orr[i].ds;j++)
{
sum[j]+=orr[i].ps;
if(sum[j]>n)
return 0;
}
}
return 1;
}
void dfs(int s)
{
for(int j=s+1;j<q;j++)
if(!flag[j])
{
flag[j]=1;
if(work())
dfs(j);
flag[j]=0;
}
int sum=0;
for(int i=0;i<q;i++)
if(flag[i])
sum+=orr[i].se;
ans=max(ans,sum);
}
int main()
{
while(cin>>n)
{
cin>>m>>q;
if(!n&&!m&&!q)
break;
for(int i=0;i<q;i++)
{
cin>>orr[i].bs>>orr[i].ds>>orr[i].ps;
orr[i].se=(orr[i].ds-orr[i].bs)*orr[i].ps;
}
memset(flag,0,sizeof(flag));
ans=0;
for(int i=0;i<q;i++)
{
flag[i]=1;
if(work())
dfs(i);
flag[i]=0;
}
cout<<ans<<endl;
}
return 0;
}


#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<string>
#include<algorithm>
#include<map>
#include<set>
#include<vector>
#include<stack>
#include<queue>
#include<climits>
#define LL long long
using namespace std;
int n,m,q;
struct node
{
int bs,ds,ps;
int se;
};
int flag[30];
node orr[30];
int ans;
bool work()
{
int sum[10];
memset(sum,0,sizeof(sum));
for(int i=0;i<q;i++)
if(flag[i])
{
for(int j=orr[i].bs;j<orr[i].ds;j++)
{
sum[j]+=orr[i].ps;
if(sum[j]>n)
return 0;
}
}
return 1;
}
void dfs(int s)
{
if(s==q)
{
int sum=0;
for(int i=0;i<m;i++)
sum+=flag[i];
ans=max(sum,ans);
}
else
{
int ok=1;
for(int i=orr[s].bs;i<orr[s].ds;i++)
{
if(flag[i]+orr[s].ps>n)
{
ok=0;
break;
}
}
if(ok)
{
for(int i=orr[s].bs;i<orr[s].ds;i++)
flag[i]+=orr[s].ps;
dfs(s+1);
for(int i=orr[s].bs;i<orr[s].ds;i++)
flag[i]-=orr[s].ps;
}
dfs(s+1);
}
}
int main()
{
while(cin>>n)
{
cin>>m>>q;
if(!n&&!m&&!q)
break;
for(int i=0;i<q;i++)
cin>>orr[i].bs>>orr[i].ds>>orr[i].ps;
memset(flag,0,sizeof(flag));
ans=0;
dfs(0);
cout<<ans<<endl;
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: