UVA301回溯法求坐火车问题的最大收益
2015-09-25 16:32
253 查看
这题站点最大为七,订单数为22,然后一开始就想着去按站点去进行搜索,然后写了n久,写不对,写残了,然后就去搜订单。
当时脑子乱了,去随便去写搜索搜订单,最后写好交上去连着T了4发,最后稍微改了下竟然以2666ms的时间险过了,然后看了
看别人交的时间,再没有比我的时间长的了,而且竟然还有一个19ms过的,实在很想看看别人19ms是怎么过的,然而别人的
代码不开放,没办法了,但比我的时间少的代码还是有很多的,另外当时我脑子乱了,其实简化时间的方法很简单,开个数组
存储经过每个站点的人数,注意是人数,最后这些人数加起来就是总价格,应该很好理解,其次在搜索的过程中,只要每个站点的
人数都不会超出容量就可以了,最后记得递归之后要还原数组。下面先贴一发我的神奇的2666ms过的代码,后面再贴一发简化时间后
的代码,其实简化时间的代码有些类似子集枚举的位向量法:
当时脑子乱了,去随便去写搜索搜订单,最后写好交上去连着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; }
相关文章推荐
- Linear Layout
- Swift - 浮点数转换成整数(四舍五入与直接截断)
- PowerDesigner快捷键【转】
- Nagios+pnp4nagios安装日记
- eclipse中文乱码
- MINA代码再次示例
- USB驱动——描述符
- 使用EMMA统计Java代码功能测试覆盖率
- Java之Concurrent(并发)包
- 记录——《C Primer Plus (第五版)》第七章编程练习第三题
- Log4j 介绍,以及配置详解
- 一行python代码
- 【hihocoder】1014. Trie树
- Javascript 保存到本地
- HDU 1023.Train Problem II【大卡特兰数】【9月25】
- 启动mysql服务命令
- Android四大组件之--BroadcastReceiver--判断网络连接
- Swift - 让StoryBoard设计视图,程序运行时都使用横屏形式
- Sql-事务
- 交叉验证