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
给两个方法的代码
代码一
#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次,如果数据量大的话第一种方法是有明显优势的