hdu4620 Fruit Ninja Extreme

48 篇文章 0 订阅

Fruit Ninja Extreme

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 900 Accepted Submission(s): 238
Special Judge


Problem Description
  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.

Input
  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.

Output
  For each test case, the first line contains one integer A, the largest number of continual bonus cuts.
  In the second line, there are A integers, K1, K2, ..., K_A, ranging from 1 to N, indicating the (Ki)-th cuts are included in the answer. The integers are in ascending order and each separated by one space. &#160;If there are multiple best solutions, any one is accepted.

Sample Input
  
  
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

Sample Output
  
  
3 1 2 3

Source

Recommend
zhuyuanchen520
水题 ,暴搜,就可以了,一个小小的剪枝,如果,当前得到的分加上,后来一直连切都比得到的结果要小于等于,可以直接剪掉!注意最后,是要排了序再输出的,这一点,错了几次, 尽量不要用 stl因为,这题 时间,卡的紧!
#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <string.h>
using namespace std;
struct node{
    int id,a[15],t,n;
    bool operator <(node b)const{return t<b.t;}
}p[35];
int re[35],tep[35],visit[250],n,w,ans;
bool cmp(node a,node b)
{
    return a<b;
}
bool cmp1(int a,int b){return a<b;}
int dfs(int step,int last,int goal)
{
    int i,sum,j;
    if(goal+n-step<=ans)
    return -1;
    for(i=step+1;i<n;i++)
    {
        if(step!=-1)
        {
            if(p[i].t-p[last].t>w)
            break;
        }
        int prime[20],num;
        for(j=0,sum=0,num=0;j<p[i].n;j++)
        {
            if(!visit[p[i].a[j]])
             visit[p[i].a[j]]=1,prime[num++]=p[i].a[j],sum++;
        }
        if(sum>=3)
        {
            tep[goal+1]=p[i].id;
            dfs(i,i,goal+1);
        }
        else
        {
             if(goal>ans)
            {
            ans=goal;
            for(j=1;j<=goal;j++)
            re[j]=tep[j];
            }
        }
        for(j=0;j<num;j++)
            visit[prime[j]]=0;
    }
    if(goal>ans)
    {
        ans=goal;
        for(j=1;j<=goal;j++)
        re[j]=tep[j];
    }
    return -1;
}
int main()
{
    int tcase,m,i,j;
    scanf("%d",&tcase);
    while(tcase--)
    {
        scanf("%d%d%d",&n,&m,&w);
        memset(visit,0,sizeof(visit));
        for(i=0;i<n;i++)
        {
            scanf("%d%d",&p[i].n,&p[i].t);
            p[i].id=i+1;
            for(j=0;j<p[i].n;j++)
            {
                scanf("%d",&p[i].a[j]);
            }
        }
        sort(p,p+n,cmp);
        ans=0;
        memset(visit,0,sizeof(visit));
        dfs(-1,0,0);
        printf("%d\n",ans);
        sort(re+1,re+ans+1,cmp1);
       for(i=1;i<=ans;i++)
       {
           if(i==1)printf("%d",re[1]);
           else printf(" %d",re[i]);
       }
        if(ans)
        printf("\n");
    }
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值