HDU4620 Fruit Ninja Extreme(搜索+剪枝)

来源:互联网 发布:淘宝shurese535假货 编辑:程序博客网 时间:2024/04/29 19:19

题目链接:传送门 


题意:

水果忍者的游戏,给定你n刀,m个水果,以及这一刀切的时间和这一刀可以切的水果的编号,如果两刀之间相隔的时间不超过v,而且这两刀都可以切超过三个水果那么这两刀就可以得一个高分。每个水果只能被切一次,求切的刀的编号使得可以得到最多的连击。


分析:

搜索+剪枝,剪枝就是当前所得到的连击数+剩下所有的刀数小于当前最优的连击数就跳出。


代码如下:

<span style="font-family:KaiTi_GB2312;font-size:18px;">#include <iostream>#include <cstring>#include <algorithm>#include <cstdio>using namespace std;const int maxn = 35;struct Fruit_cut{    int num,t,id,c[10];    bool operator <(const struct Fruit_cut &tmp)const{        return t<tmp.t;    }}cut[maxn];int n,m,v;int vis[210];int ans[maxn],tot,tlong;int tmp[maxn];void dfs(int id,int pre){    if(n-id+tlong<=tot) return;    for(int i=id+1;i<=n;i++){        int num = 0;        for(int j=0;j<cut[i].num;j++){            int pos = cut[i].c[j];            if(!vis[pos]) num++;            vis[pos]++;        }        if((cut[i].t-pre<=v||!tlong)&&num>=3){            tmp[tlong++]=cut[i].id;            dfs(i,cut[i].t);            tlong--;        }        for(int j=0;j<cut[i].num;j++){            int pos = cut[i].c[j];            vis[pos]--;        }    }    if(tlong>tot){        tot = tlong;        for(int i=0;i<tlong;i++){            ans[i]=tmp[i];        }    }}int main(){    int t;    scanf("%d",&t);    while(t--){        scanf("%d%d%d",&n,&m,&v);        for(int i=1;i<=n;i++){            scanf("%d%d",&cut[i].num,&cut[i].t);            cut[i].id=i;            for(int j=0;j<cut[i].num;j++){                scanf("%d",&cut[i].c[j]);            }        }        sort(cut+1,cut+n+1);        tot=0,tlong=0;        memset(vis,0,sizeof(vis));        memset(ans,0,sizeof(ans));        dfs(0,cut[1].id);        sort(ans,ans+tot);        printf("%d\n",tot);        for(int i=0;i<tot-1;i++)            printf("%d ",ans[i]);        printf("%d\n",ans[tot-1]);    }    return 0;}</span>

0 0
原创粉丝点击