HDU 4620 Fruit Ninja Extreme 暴搜

来源:互联网 发布:同志漫画软件 编辑:程序博客网 时间:2024/05/01 01:24

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

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;}


原创粉丝点击