首页 > 搜索 > DFS搜索 > HDU 4620-Fruit Ninja Extreme-DFS-[解题报告]HOJ
2015
09-17

HDU 4620-Fruit Ninja Extreme-DFS-[解题报告]HOJ

Fruit Ninja Extreme

问题描述 :

  Cut or not to cut, it is a question.
  In Fruit Ninja, comprising three or more fruit in one cut gains extra bonuses. This kind of cuts are called bonus cuts.
  Also, performing the bonus cuts in a short time are considered continual, iff. when all the bonus cuts are sorted, the time difference between every adjacent cuts is no more than a given period length of W.
  As a fruit master, you have predicted the times of potential bonus cuts though the whole game. Now, your task is to determine how to cut the fruits in order to gain the most bonuses, namely, the largest number of continual bonus cuts.
  Obviously, each fruit is allowed to cut at most once. i.e. After previous cut, a fruit will be regarded as invisible and won’t be cut any more.
  In addition, you must cut all the fruit altogether in one potential cut. i.e. If your potential cut contains 6 fruits, 2 of which have been cut previously, the 4 left fruits have to be cut altogether.

输入:

  There are multiple test cases.
  The first line contains an integer, the number of test cases.
  In each test case, there are three integer in the first line: N(N<=30), the number of predicted cuts, M(M<=200), the number of fruits, W(W<=100), the time window.
  N lines follows.
  In each line, the first integer Ci(Ci<=10) indicates the number of fruits in the i-th cuts.
  The second integer Ti(Ti<=2000) indicate the time of this cut. It is guaranteed that every time is unique among all the cuts.
  Then follow Ci numbers, ranging from 0 to M-1, representing the identifier of each fruit. If two identifiers in different cuts are the same, it means they represent the same fruit.

输出:

  There are multiple test cases.
  The first line contains an integer, the number of test cases.
  In each test case, there are three integer in the first line: N(N<=30), the number of predicted cuts, M(M<=200), the number of fruits, W(W<=100), the time window.
  N lines follows.
  In each line, the first integer Ci(Ci<=10) indicates the number of fruits in the i-th cuts.
  The second integer Ti(Ti<=2000) indicate the time of this cut. It is guaranteed that every time is unique among all the cuts.
  Then follow Ci numbers, ranging from 0 to M-1, representing the identifier of each fruit. If two identifiers in different cuts are the same, it means they represent the same fruit.

样例输入:

1
4 10 4
3 1 1 2 3
4 3 3 4 6 5
3 7 7 8 9
3 5 9 5 4

样例输出:

3
1 2 3

看到水果忍者一激动,这么长题目一气呵成。。结果后来才知道好多地方理解错了意思。

题意:

首先,一刀切三个或三个以上,连续(两刀之间时间差<=w)这样切,得分最高。

要求算最多可以连续切三个或三个以上多少刀。

给的是:n,m,w 一共多少刀,一共多少水果,两刀时间差的最大值

然后每行 c,t,c1,c2,c3……表示t时刻切了一刀,这一刀切了c个水果,分别编号是c1,c2,c3…..

题目其实是说,给的刀中,可以选择这一刀切还是不切,只要能满足那两个要求的最大值就行了

解法:

先把所有刀按出现的时间排序,

然后开始dfs,记录每一条路咯

要注意的几点:

1、在标记出现过的水果时,很麻烦,如果只用0和1表示是否出现过的话,回溯时不好还原,

那么就把这一刀所有水果的vis++,这样都是非0,后面都不影响,回溯时再–,就可以还原

2、判断是否符合连续&&三个或者三个以上时,还要加上,此时存的长度变量tmpl为0时也符合,表示是第一个,所以可以

3、输出时,按照输入的顺序编号输出

4、要加剪枝啦

#include <iostream>
#include <cstring>
#include <string>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <cmath>
using namespace std;

struct node
{
    int t,p[15],c,id;
}cut[35];

bool cmp(node x,node y)
{
    return x.t<y.t;
}

int T,longe,ans[35],tmpa[35],tmpl,n,w,m,vis[205],num;

void dfs(int pos,int lastt)
{
    if(n-pos+tmpl<=longe) return;//后面每一刀都切 还比最长的短
    int num,i,j,tmp;
    for(i=pos+1;i<=n;i++)
    {
        for(j=1,num=0;j<=cut[i].c;j++)//统计没出现过的个数
        {
            tmp=cut[i].p[j];
            if(vis[tmp]==0)
                num++;
            vis[tmp]++;//便于还原
        }
        if((cut[i].t-lastt<=w||!tmpl)&&num>=3)
        {
            tmpl++;
            tmpa[tmpl]=cut[i].id;
            dfs(i,cut[i].t);
            tmpl--;
        }
        for(j=1;j<=cut[i].c;j++)
        {
            tmp=cut[i].p[j];
            vis[tmp]--;
        }
    }
    if(longe<tmpl)
    {
        longe=tmpl;
        for(j=0;j<longe;j++)
            ans[j]=tmpa[j+1];
    }
}

int main()
{
    int i,j;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d%d",&n,&m,&w);
        for(i=1;i<=n;i++)
        {
            scanf("%d%d",&cut[i].c,&cut[i].t);
            for(j=1;j<=cut[i].c;j++)
                scanf("%d",&cut[i].p[j]);
            cut[i].id=i;
        }
        sort(cut+1,cut+n+1,cmp);
        memset(vis,0,sizeof vis);
        longe=0;tmpl=0;
        dfs(0,cut[1].t);

        sort(ans,ans+longe);
        printf("%d\n",longe);
        for(i=0;i<longe-1;i++)
            printf("%d ",ans[i]);
        printf("%d\n",ans[longe-1]);
    }
    return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

参考:http://blog.csdn.net/u011032846/article/details/10361677