【zzuli】1985 即将到来的新生赛 dp or dfs

1985: 即将到来的新生赛
Description

新生赛马上就要到来了。为了举办这次比赛,学校也是大费苦心。由于时间紧迫,要准备的事情太多,人员安排也是很伤脑子。身为一个聪明的acmer,这点小事对你来说应该是So easy!
距离新生赛开始剩余100个小时,现在还剩余m项任务。每个任务都有开始时间,结束时间和收益。现在想知道怎么安排这些任务使人员安排的效率最大(收益最高)。
注:同一时间只能做一个任务, 一个任务结束后可以立马开始另外一个任务,也就是说下一个任务的开始时间可以等于正在做的任务的结束时间。由于有些任务是有时间上的冲突, 所以这些任务是选作,可以不用全部完成。
Input

输入第一行为整数T,表示有T组测试数据。
每组测试数据第一行为一个整数m,表示剩余任务。随后m行,每行三个整数b,e和v分别表示其中一项活动的开始时间,结束时间和收益。(0<=b < e<=100 ,0<=v<=10000,1<=m<=20)
Output

输出最高收益。
Sample Input

1
4
0 5 10
3 7 14
5 9 7
6 9 8
Sample Output

18
HINT

Source

郑州轻工业学院2016年新生程序设计大赛

给两个方法的代码

代码一

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
struct node{
    int a,b,v;
}aa[22];int ans,n,dp[22];
bool cmp(node x,node y){
    return x.a<y.a;
}
int sove(int x)
{
    int max=0;
    if(dp[x]>0) return dp[x];
    for(int i=x+1;i<n;i++)
        if(aa[i].a>=aa[x].b&&sove(i)>max)
            max=sove(i);
    return dp[x]=max+aa[x].v;
}
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        memset(dp,-1,sizeof(dp));
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
            scanf("%d%d%d",&aa[i].a,&aa[i].b,&aa[i].v);
        sort(aa+1,aa+(++n),cmp);
        printf("%d\n",sove(0));
    }
    return 0;
}

代码二

#include<stdio.h>
#include<algorithm>
using namespace std;
struct node{
    int b,e,v;
}a[25];int n,ans;
void dfs(int t,int r,int sum){
    if(t==n) {
        if(sum>ans) ans=sum;
        return ;
    }
    dfs(t+1,r,sum);
    if(a[t].b>=r) dfs(t+1,a[t].e,sum+a[t].v);
}
bool cmp(node x,node y){
    return x.e<y.e;
}
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d",&n);
        for(int i=0;i<n;i++)
            scanf("%d%d%d",&a[i].b,&a[i].e,&a[i].v);
        sort(a,a+n,cmp);
        ans=0; dfs(0,0,0);
        printf("%d\n",ans);
    }
    return 0;
}

按样例的数据 方法一进行了5次递归 方法二进行了18次,如果数据量大的话第一种方法是有明显优势的

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值