题目链接:

http://acm.hdu.edu.cn/showproblem.php?pid=4620

题目大意:

切水果。给n刀,每刀的时间,每刀切的水果的种类。求能切的最多的刀数,使得每相邻的两刀时间差不超过给定的w.前面切了的水果不能再切,每刀至少要切不少于三个的新的水果。

解题思路:

直接一个一个的暴搜的话会超时。

这里从每相邻两刀时间间隔不能超过w来考虑剪枝。问题抽象出来就是从给定的刀中选,相邻的选的话,不如按时间排序从小到大选,这样的效果更好,而且还可以剪枝。

本题排序剪枝很关键。

代码:

#include<iostream>
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<string>
#include<cstring>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<stack>
#include<list>
#include<queue>
#define eps 1e-6
#define INF 0x1f1f1f1f
#define PI acos(-1.0)
#define ll __int64
#define lson l,m,(rt<<1)
#define rson m+1,r,(rt<<1)|1
#pragma comment(linker, "/STACK:1024000000,1024000000")
using namespace std; //freopen("data.in","r",stdin);
//freopen("data.out","w",stdout); int hav[220]; //hav[i]表示已经切了的水果i
int ti[35],num[35],fru[35][12],pos[35];
int n,m,w; struct Node
{
int sa[35];
int cnt;
}ans,temp; //对时间进行排序后,可以大大剪枝。
void dfs(int cur)
{
if(temp.cnt>ans.cnt)
ans=temp;
if(n-cur+temp.cnt<=ans.cnt)//这个剪枝很关键
return ;
for(int i=cur+1;i<=n;i++) //排序后可以剪枝
{
int pp=pos[i];
int aa[12];
if(temp.cnt&&ti[pp]-ti[pos[cur]]>w) //如果前面至少选了一个
break;
int sum=0; //前面一个都没选的话,任何一个都可以作为第一个
for(int j=1;j<=num[pp];j++)
{
aa[j]=hav[fru[pp][j]];
if(!aa[j])
sum++;
}
if(sum<3)
continue;
for(int j=1;j<=num[pp];j++)
hav[fru[pp][j]]|=1; temp.sa[++temp.cnt]=pp;
dfs(i);
temp.cnt--;
for(int j=1;j<=num[pp];j++)
hav[fru[pp][j]]=aa[j];
}
}
bool cmp(int a,int b)
{
return ti[a]<ti[b];
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d%d%d",&n,&m,&w);
for(int i=1;i<=n;i++)
{
scanf("%d%d",&num[i],&ti[i]);
for(int j=1;j<=num[i];j++)
scanf("%d",&fru[i][j]);
pos[i]=i;
}
sort(pos+1,pos+n+1,cmp); //对时间进行排序
ans.cnt=0,temp.cnt=0;
memset(hav,0,sizeof(hav));
dfs(0);
printf("%d\n",ans.cnt);
sort(ans.sa+1,ans.sa+ans.cnt+1);//输出按升序来
if(!ans.cnt)
continue;
printf("%d",ans.sa[1]);
for(int i=2;i<=ans.cnt;i++)
printf(" %d",ans.sa[i]);
putchar('\n');
}
return 0;
}

dfs-hdu-4620-Fruit Ninja Extreme的更多相关文章

  1. hdu 4620 Fruit Ninja Extreme

    Fruit Ninja Extreme Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Othe ...

  2. hdu 4620 Fruit Ninja Extreme(状压+dfs剪枝)

    对t进行从小到大排序(要记录ID),然后直接dfs. 剪枝的话,利用A*的思想,假设之后的全部连击也不能得到更优解. 因为要回溯,而且由于每次cut 的数目不会超过10,所以需要回溯的下标可以利用一个 ...

  3. HDU 4620 Fruit Ninja Extreme 搜索

    搜索+最优性剪枝. DFS的下一层起点应为当前选择的 i 的下一个,即DFS(i + 1)而不是DFS( cur + 1 ),cur+1代表当前起点的下一个.没想清楚,TLE到死…… #include ...

  4. HDU 4620 Fruit Ninja Extreme(2013多校第二场 剪枝搜索)

    这题官方结题报告一直在强调不难,只要注意剪枝就行. 这题剪枝就是生命....没有最优化剪枝就跪了:如果当前连续切割数加上剩余的所有切割数没有现存的最优解多的话,不需要继续搜索了 #include &l ...

  5. HDU 4620 Fruit Ninja Extreme 暴搜

    题目大意:题目就是描述的水果忍者. N表示以下共有 N种切水果的方式. M表示有M个水果需要你切. W表示两次连续连击之间最大的间隔时间. 然后下N行描述的是 N种切发 第一个数字C表示这种切法可以切 ...

  6. hdu4620 Fruit Ninja Extreme

    Fruit Ninja Extreme Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...

  7. hdu 4000 Fruit Ninja 树状数组

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4000 Recently, dobby is addicted in the Fruit Ninja. ...

  8. HDU 4116 Fruit Ninja

    http://acm.hdu.edu.cn/showproblem.php?pid=4116 题意:给N个圆,求一条直线最多能经过几个圆?(相切也算) 思路:枚举中心圆,将其他圆的切线按照极角排序,并 ...

  9. hdu - 3952 Fruit Ninja(简单几何)

    思路来自于:http://www.cnblogs.com/wuyiqi/archive/2011/11/06/2238530.html 枚举两个多边形的两个点组成的直线,判断能与几个多边形相交 因为最 ...

  10. HDU 4000 Fruit Ninja 树状数组 + 计数

    给你N的一个排列,求满足:a[i] < a[k] < a[j] 并且i < j < k的三元组有多少个. 一步转化: 求出所有满足 a[i] < a[k] < a[ ...

随机推荐

  1. select into from 和 insert into select 的用法和区别(转)

    转自:http://www.studyofnet.com/news/182.html select into from 和 insert into select都是用来复制表,两者的主要区别为: se ...

  2. 用jmeter进行多用户并发压力测试 [转]

    近日manager要求对项目进行压力测试,开始对jmeter进行了研究.jmeter是Apache一个开源项目,可对各种项目进行测试,甚至包括junit. 测试要求如下,多用户同时登陆web应用程序, ...

  3. 解决Sublime Text3莫名的中文乱码问题

    有好几回用Sublime Text3写着中英混杂的文字的时候,会突然就弹出警告说什么编码不行,然后点击确定后,原来的中文全都乱码了: 然后即使按ctrl+z撤回也没用,重新打开也没用,用记事本的转换a ...

  4. 配置分割Tomcat日志

    安装cronolog 官网下载:http://cronolog.org/usage.html ./configuremake;make install 或者 yum install cronolog ...

  5. (C)高级排序法

    1.快速排序法 //方法1 从大到小 #include <iostream.h> void run(int* pData,int left,int right) { int i,j; in ...

  6. [lua]笔试-按字典序列出指指定的序列的位置

    计算方法: n的阶乘记为f(n), s为输入序列, sub(i)为s的i到n的子序列.A(i)为第i位对应的字母在子序列sub(i)中的字典顺序 N(s) = sum_{1,n} T(i)*(A(i) ...

  7. BZOJ 3038: 上帝造题的七分钟2

    3038: 上帝造题的七分钟2 Description XLk觉得<上帝造题的七分钟>不太过瘾,于是有了第二部. "第一分钟,X说,要有数列,于是便给定了一个正整数数列. 第二分 ...

  8. swift菜鸟入门视频教程-07-闭包

    本人自己录制的swift菜鸟入门,欢迎大家拍砖.有什么问题能够在这里留言. 主要内容: 闭包表达式(Closure Expressions) 跟随闭包(Trailing Closures) 值捕获(C ...

  9. 【QT相关】类头文件解读、QT编辑模式、读取text文本

    Wizard产生的头文件类包含了必须的#include文件.构造函数.析构函数和UI对象: #include <QMainWindow> namespace Ui {class Notep ...

  10. BZOJ 2016: [Usaco2010]Chocolate Eating( 二分答案 )

    因为没注意到long long 就 TLE 了... 二分一下答案就Ok了.. ------------------------------------------------------------ ...