HDU 4620 Fruit Ninja Extreme 暴搜

题目大意:题目就是描述的水果忍者。

N表示以下共有 N种切水果的方式。

M表示有M个水果需要你切。

W表示两次连续连击之间最大的间隔时间。

然后下N行描述的是 N种切发

第一个数字C表示这种切法可以切多少个水果。

第二个数字表示这种切法所处在的时间。

后C个数字表示此时这种切法所切掉的水果编号。

注意:同时切3个以上才表示连击,一个水果最多只能切一次。


思路:直接暴搜,再去加剪枝。

 

#include <iostream>

#include <cstdio>

#include <algorithm>

#include <vector>

#include <cstring>

using namespace std;



int gap,n,m;

int vis[205];



int tans[35];//开手动栈,不然容易超时

int ans[35];

int tanstop;

int anstop;





struct node

{

    vector<int>num;

    int cnt;

    int time;

    int id;

    bool operator < (const node &cmp) const

    {

        return time<cmp.time;

    }

}cut[35];





void dfs(int ttime,int pos)

{

    if(m-pos+tanstop<=anstop) return;//如果之后的全部放上来还比当前ANS小,那就不用继续了  A*思想 

    for(int i=pos+1;i<=m;i++)

    {

        if(cut[i].time-ttime<=gap||!tanstop)//每一次都可以作为起点。所以加上!tanstop   

        {

            int tot=0;

            int SIZE=cut[i].num.size();

            for(int j=0;j<SIZE;j++)

            {

                if(vis[cut[i].num[j]]==0)

                {

                    tot++;

                }

                vis[cut[i].num[j]]++;

            }

            if(tot>=3)

            {

                tans[tanstop++]=cut[i].id;

                dfs(cut[i].time,i);

                tanstop--;

            }

            for(int j=0;j<SIZE;j++)

                vis[cut[i].num[j]]--;

        }

        else break;//如果此时时间已无法连击  后面的也就不行了

    }

        if(tanstop>anstop)

        {

            anstop=0;

            for(int i=0;i<tanstop;i++)

            ans[anstop++]=tans[i];

        }

    

}



int main()

{

    int T;

    scanf("%d",&T);

    while(T--)

    {

        tanstop=anstop=0;



        memset(vis,0,sizeof(vis));



        scanf("%d%d%d",&m,&n,&gap);



        for(int i=1;i<=m;i++)

        {

            cut[i].num.clear();

            scanf("%d%d",&cut[i].cnt,&cut[i].time);

            cut[i].id=i;

            for(int j=0;j<cut[i].cnt;j++)

            {

                int tmp;

                scanf("%d",&tmp);

                cut[i].num.push_back(tmp);

            }

            if(cut[i].cnt<=2){i--;m--;}

        }

        

        sort(cut+1,cut+m+1);//按时间把切水果的方式排序  方便DFS



        dfs(1,0);





        printf("%d\n",anstop);



        sort(ans,ans+anstop);//要求升序输出



        for(int i=0;i<anstop-1;i++)

        printf("%d ",ans[i]);

        printf("%d\n",ans[anstop-1]);

    }

    return 0;

}






 

 

你可能感兴趣的:(ext)