HDU 2614 Beat(dfs+回溯)

来源:互联网 发布:ds数据精灵注册机 编辑:程序博客网 时间:2024/05/18 00:43

题目来源:HDU 2614

Beat

                                                                Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Problem Description
Zty is a man that always full of enthusiasm. He wants to solve every kind of difficulty ACM problem in the world. And he has a habit that he does not like to solve
a problem that is easy than problem he had solved. Now yifenfei give him n difficulty problems, and tell him their relative time to solve it after solving the other one.
You should help zty to find a order of solving problems to solve more difficulty problem. 
You may sure zty first solve the problem 0 by costing 0 minute. Zty always choose cost more or equal time’s problem to solve.
 
Input
The input contains multiple test cases.
Each test case include, first one integer n ( 2< n < 15).express the number of problem.
Than n lines, each line include n integer Tij ( 0<=Tij<10), the i’s row and j’s col integer Tij express after solving the problem i, will cost Tij minute to solve the problem j.
 
Output
For each test case output the maximum number of problem zty can solved.

Sample Input
3
0 0 0
1 0 1
3
1 0 0
0 2 2
5
1 0 1
1 1 0
0 0 2 3 1
0 1 2 3 1
0 0 0 3 1
0 0 0 0 0
0 0 0 0 2
 
Sample Output
3
2
4
Hint
Hint: sample one, as we know zty always solve problem 0 by costing 0 minute.
So after solving problem 0, he can choose problem 1 and problem 2, because T01 >=0 and T02>=0.
But if zty chooses to solve problem 1, he can not solve problem 2, because T12 < T01.
So zty can choose solve the problem 2 second, than solve the problem 1.

心路历程:题目让求最大解题数目,那么很容易想到用dfs,唯一不同的是当搜索到一个状态的时候,另一个已访问过的状态也会参与到目前正在访问的状态,所以需要回溯。
注意:1.题目中指出每次都是从第0题开始做的
           2.由于最大答案是不断更换的,如果开全局变量的话,当访问回到上一层或几层时,num的值不易更改,所以不妨作为函数的参数,只与这层函数有关

代码如下:
#include <iostream>#include <stdio.h>#include <string.h>#include <algorithm>#include <stack>using namespace std;int n,ans;int v[20],arr[20][20];void dfs(int cur,int time,int num)//cur保存的是现在做完了第cur题,time保存的是做cur题用的时间,num保存的是做题的数量{     int nxt,co=0;     for(nxt=0;nxt<n;nxt++)     {         if(v[nxt]==1||nxt==cur)//注意不会重复做自身题         {             continue;         }         else if(arr[cur][nxt]>=time)         {             v[nxt]=1;             dfs(nxt,arr[cur][nxt],num+1);             v[nxt]=0;//一个分支访问完毕,使nxt变为未访问过             co=1;//意思是还可以往下做题         }     }     if(co==0)//当无题可做时,比较答案     {         ans=max(ans,num);     }}int main(){    int i,j;    while(scanf("%d",&n)==1)    {        memset(v,0,sizeof(v));//初始化visit        for(i=0;i<n;i++)        {            for(j=0;j<n;j++)            {                scanf("%d",&arr[i][j]);            }        }        ans=1;//至少会有一道题        v[0]=1;//初始化第0题        dfs(0,0,1);        printf("%d\n",ans);    }    return 0;}