POJ1015 Jury Compromise dfs的实现
2015-12-27 13:31
387 查看
做ACM练习题目已经两个年头了,最开始脑子很混乱,后来慢慢有了感觉,AC率也大幅度提高,接下来就一些经典问题做一下回顾,这些问题涵盖了算法的多个方面,相对来说有一些较为全面的总结,也是我这些年劳动成果的一些体现,今天带来的是另一道经典题目1015的dfs实现。
首先需要说明的是,这道题系统要求是用动态规划来做,并且只有动态规划能够在规定时间内跑完。这里我要说的是dfs的实现,这种实现是不能AC的,但是算法是对的,结果也是对的。之所以不能AC还要写出来,一是因为这道题目的动态规划算法已经有其他博主提供,第二是本题的动态规划算法非常复杂,一般很难想到,可以说一般参赛选手拿到题目首先想到的应该是深搜,虽然我的这套代码不能AC,但也可以作为一种算法的学习,毕竟做题不单单是为了AC,也是为了总结。
一般来说深搜有几种方法:
1.使用堆栈,stack,每循环一次将变量放入stack中,while(!s.empty()),当栈中无数据循环结束;
2.使用还原现场的方法,嵌套递归:
3.直接使用循环嵌套递归:
本题我们采用的是第三种方式。
dfs(int tp,int td,int already,int start,int *tc)
是我们的递归函数,其中tp指已经选择的那些候选者的正方赞成票,td指反方赞成票,already指已经选择了多少个候选者,和上面的current相似。start代表从第start个候选者往后选,因为之前的已经遍历过了,tc是临时数组,用于存储已经选了哪些候选者。
这道题目可以作为第三种深搜方式很好的学习例子。
首先需要说明的是,这道题系统要求是用动态规划来做,并且只有动态规划能够在规定时间内跑完。这里我要说的是dfs的实现,这种实现是不能AC的,但是算法是对的,结果也是对的。之所以不能AC还要写出来,一是因为这道题目的动态规划算法已经有其他博主提供,第二是本题的动态规划算法非常复杂,一般很难想到,可以说一般参赛选手拿到题目首先想到的应该是深搜,虽然我的这套代码不能AC,但也可以作为一种算法的学习,毕竟做题不单单是为了AC,也是为了总结。
一般来说深搜有几种方法:
1.使用堆栈,stack,每循环一次将变量放入stack中,while(!s.empty()),当栈中无数据循环结束;
2.使用还原现场的方法,嵌套递归:
ifVisited[i]=true;//设置记号 execute();//进入下一步递归 ifVisited[i]=false;//还原现场
3.直接使用循环嵌套递归:
if(current==maxSize){ ...... } for(i=current+1;i<=maxSize;i++){ execute(i); }
本题我们采用的是第三种方式。
dfs(int tp,int td,int already,int start,int *tc)
是我们的递归函数,其中tp指已经选择的那些候选者的正方赞成票,td指反方赞成票,already指已经选择了多少个候选者,和上面的current相似。start代表从第start个候选者往后选,因为之前的已经遍历过了,tc是临时数组,用于存储已经选了哪些候选者。
这道题目可以作为第三种深搜方式很好的学习例子。
#include<iostream> #include<cmath> using namespace std; int n,m; int d[201],p[201]; int c[21]; int pNum,dNum; void dfs(int tp,int td,int already,int start,int *tc){ if(already==m){ if(abs(td-tp)<abs(pNum-dNum)){ pNum=tp; dNum=td; for(int i=1;i<=m;i++){ c[i]=tc[i]; } return; } else if(abs(td-tp)==abs(pNum-dNum)&&(td+tp)>(pNum+dNum)){ pNum=tp; dNum=td; for(int i=1;i<=m;i++){ c[i]=tc[i]; } return; } else{ return; } } if(m-already>n-start){ return; } for(int i=start+1;i<=n;i++){ tc[already+1]=i; dfs(tp+p[i],td+d[i],already+1,i,tc); } return; } void calc(){ pNum=201; dNum=-201; int tc[21]; for(int i=1;i<=n;i++){ tc[1]=i; dfs(p[i],d[i],1,i,tc); } } int main(){ int totalCase=0; cin>>n>>m; while(n!=0){ totalCase++; for(int i=1;i<=n;i++){ cin>>p[i]>>d[i]; } calc(); cout<<"Jury #"<<totalCase<<endl; cout<<"Best jury has value "<<pNum<<" for prosecution and value "; cout<<dNum<<" for defence:"<<endl; for(int i=1;i<=m;i++){ cout<<" "<<c[i]; } cout<<endl; cin>>n>>m; } return 0; }
相关文章推荐
- 深入理解linux操作系统中的高端内存
- HTML中的特殊符号
- [leetcode] 228. Summary Ranges 解题报告
- C#程序调用cmd执行命令-MySql备份还原
- Python 线程(threading) 进程(multiprocessing)
- android读取系统相册,设置头像
- Redis生存时间
- 【Java EE 学习 79 上】【mybatis 基本使用方法】
- Android Animation初识
- 程序员必知必会的10道算法
- LeetCode Spiral Matrix
- AS下载地址
- 约瑟夫问题
- linux red hat 给普通用户开启root权限
- 约瑟夫问题
- Eclipse错误:The superclass "javax.servlet.http.HttpServlet" was not found on the Java Build Path
- 进程间通信 之 管道
- 利用回调函数实现的一个简单确认对话框。
- Add Binary
- 华为GVRP理解