题目描述:
输入输出:
解释:
贪心思想。
为了在规定时间段尽可能赢取更多的钱,那么首先考虑的肯定是金额大的,故将每个小游戏按照金额从大到小排序(可以采用结构体);
题目要求每个小游戏 “在规定期限 ti 前完成” ,意思是若某游戏ddl为3,那么它在1~3时间段完成均可;
那么,不妨设立在每个时间段设立一个flag,用来标记每个时间段是否已经被使用(假设未被使用可用);从已经排好序的第一个小游戏开始(一层循环),已知它的ddl(表示它最晚必须完成的时间),从这个ddl不断往前寻找直到1,若能寻找到一个时间段的flag为0(未被占用),则将该时间段分配给该小游戏,将flag置为1(表示占用),并直接break开始下一轮循环(下一个小游戏);若是从ddl往前寻找到时间段1的时候仍然无法找到一个时间段符合,则说明该游戏一定无法被完成,那么能获得的金额就要减去该游戏的金额。
AC代码:
#include<bits/stdc++.h>
using namespace std;
const int N=510;
int m,n;//总金额,总时段数
struct AAA{
int ddl;
int value;
bool flag=0;//某时段是否占用 ,0表示未被占用
}a[N];
bool cmp(AAA x,AAA y)
{
return x.value>y.value;
}
int main()
{
while(scanf("%d%d",&m,&n)!=EOF)
{
int i,j;
for(i=1;i<=n;i++)
{
int ddl;
scanf("%d",&ddl);
a[i].ddl=ddl;
}
for(i=1;i<=n;i++)
{
int value;
scanf("%d",&value);
a[i].value=value;
}
sort(a+1,a+n+1,cmp);
for(i=1;i<=n;i++)
{
for(j=a[i].ddl;j>=1;j--)
{
if(a[j].flag==0)
{
a[j].flag=1;//该时段被使用
break;
}
if(j==1)//j到1还没break说明没位置给这个任务了
m-=a[i].value;
}
}
printf("%d\n",m);
}
return 0;
}
写在最后:文章多有不足,代码也不一定简洁,欢迎各位大佬指正!