动态规划(总是时间超限)

越氏羿界 2014-04-18 10:12:09
1080: 力所能及
时间限制: 3 Sec 内存限制: 256 MB
提交: 169 解决: 17
[提交][状态][讨论版]
题目描述

中南大学ACM协会又到了新老交替的时候了,于是在下一批优秀学子到来的时候,协会也就要开始招新了。

ACM协会下学期计划要完成N项任务,且每项任务都可由一个人独立完成。对于每项任务均会有一个难度值X和完成该项任务后对协会的贡献值V。

这时协会一共收到了M个新生的简历,对于每个新生,他们都会有一个衡量办事能力的二元组(S,T),表示这个新生可以完成难度在S、T之间(包括S、T)的任务,同时每个人也会有一个解决任务数量的上限K,也就说这个新生最多只会完成K项任务,要不然他就会因过度疲倦而讨厌协会了。

现在ACM协会的招新人员想知道,对于这M个新生中的某一个,如果把他招进来,最多能带给协会多大的贡献值呢?


输入

输入包含多组测试数据。

对于每组测试数据,第一行包含一个正整数N (1<=N<=10000),表示ACM下学期计划要完成N项任务。接下来一共有N行,每行均包含两个整数X、V (0<=X<=10^9, -1000<=V<=1000),表示该项任务的难度值为X,完成该项任务后对协会的贡献值为V。接下来一行包含一个正整数M (1<=M<=10000),表示协会一共收到了M个新生的简历。再接下来一共有M行,每行包含三个整数S、T、K (0<=S<=T<=10^9, 1<=K<=10000),表示这个新生可以完成难度在S、T之间(包括S、T)的任务,且最多只会完成K项任务。


输出

对于每组测试数据,一共输出M行,每行输出一个整数表示如果将对应的新生招入协会,最多能给协会带来多大的贡献值。每组数据结尾输出一个空行。


样例输入
3
2 3
0 1
1 -2
3
0 3 1
0 3 3
1 1 2
样例输出
3
4
0


提示

由于数据量较大,推荐使用scanf/printf。

我所编写的源代码(或者您帮我编写一个程序,给我作为参考,谢谢):
#include<iostream>
#include<algorithm> //qsort的头文件
#define H 10000
using namespace std;

struct task
{
long x;
long v;
};

struct resume
{
long s,t;
int k;
};

int cmp1( const void *a ,const void *b); //比较函数
int cmp3( const void *a ,const void *b);
int lower_bound(struct task array[],int n,int b) ;
int upper_bound(struct task array[], int n, int b);

int main()
{
int con,i,a;
int e;
struct task ta[H];
struct resume re[H];
int N,M;
while(cin >> N)
{
for(i=0;i<N;i++) //输入任务、新人
cin >> ta[i].x >> ta[i].v ;
cin >> M ;
for(i=0;i<M;i++)
cin >> re[i].s >> re[i].t >> re[i].k ;
qsort(ta,N,sizeof(ta[0]),cmp1); //快速排序
for(e=0;e<M;e++)
{
int min,max;
qsort(ta,N,sizeof(ta[0]),cmp1); //快速排序
min=lower_bound(ta,N,re[e].s);
max=upper_bound(ta,N,re[e].t);
qsort(&ta[min],max-min+1,sizeof(ta[min]),cmp3); //对符合的任务进行排序...cmp3
con=0;
if(re[e].k>=(max-min+1))
{
for(a=min;a<(max+1);a++)
if(ta[a].v>0)con=con+ta[a].v; //else接的是最近那if
}
else
{
int uo=0;
for(a=min;uo<re[e].k && a<(max+1);a++)
{
if(ta[a].v>0) { uo++; con=con+ta[a].v; } //这里这里<0的时候a是不算的 所以要用另一个变量来算
}
}
cout << con << endl ;
}
}
return 0;
}

int cmp1( const void *a ,const void *b) //比较函数的函数体
{
return (*(task *)a).x < (*(task *)b).x ? 1 : -1;
}

int cmp3( const void *a ,const void *b) //比较函数的函数体
{
return (*(task *)a).v < (*(task *)b).v ? 1 : -1;
}


int lower_bound(struct task array[],int n,int b)
{
int left, right, middle;

left = 0;
right = n - 1;

while (left < right)
{
middle = (left + right) / 2;
if (array[middle].x > b)
{
right = middle;
}
else if(array[middle].x < b)
{
left = middle + 1;
}
else return middle;
}
return left;
}

int upper_bound(struct task array[], int n, int b)
{
int left, right, middle;

left = 0;
right = n - 1;

while (left < right)
{
middle = (left + right) / 2;
if (array[middle].x < b)
{
left = middle + 1;
}
else if(array[middle].x > b)
{
right = middle;
}
else return middle;
}
return left;
}
...全文
291 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
越氏羿界 2014-04-19
  • 打赏
  • 举报
回复
引用 8 楼 FancyMouse 的回复:
[quote=引用 4 楼 u014772810 的回复:] [quote=引用 1 楼 FancyMouse 的回复:] 提示 由于数据量较大,推荐使用scanf/printf。
为什么用这两个会 减少数据量呢?????[/quote] 不是减少数据量,是iostream比stdio慢(尤其是vc的运行库),导致同样的数据stdio能过iostream可能会TLE。[/quote] 那这程序还有救吗????
FancyMouse 2014-04-19
  • 打赏
  • 举报
回复
引用 4 楼 u014772810 的回复:
[quote=引用 1 楼 FancyMouse 的回复:] 提示 由于数据量较大,推荐使用scanf/printf。
为什么用这两个会 减少数据量呢?????[/quote] 不是减少数据量,是iostream比stdio慢(尤其是vc的运行库),导致同样的数据stdio能过iostream可能会TLE。
越氏羿界 2014-04-18
  • 打赏
  • 举报
回复
引用 5 楼 u014772810 的回复:
[quote=引用 1 楼 FancyMouse 的回复:] 提示 已改,不过现在是输出朝鲜了。。。。这又是什么原因???? 源代码: #include<iostream> #include<cstdio> #include<algorithm> //qsort的头文件 #define H 10000 using namespace std; struct task { long x; long v; }; struct resume { long s,t; int k; }; int cmp1( const void *a ,const void *b); //比较函数 int cmp3( const void *a ,const void *b); int lower_bound(struct task array[],int n,int b) ; int upper_bound(struct task array[], int n, int b); int main() { int con,i,a; int e; struct task ta[H]; struct resume re[H]; int N,M; while(scanf("%d",&N)) { for(i=0;i<N;i++) //输入任务、新人 scanf("%ld%ld",&ta[i].x, &ta[i].v); scanf("%d",&M) ; for(i=0;i<M;i++) scanf("%ld%ld%d",&re[i].s, &re[i].t,&re[i].k); qsort(ta,N,sizeof(ta[0]),cmp1); //快速排序 for(e=0;e<M;e++) { int min,max; qsort(ta,N,sizeof(ta[0]),cmp1); //快速排序 min=lower_bound(ta,N,re[e].s); max=upper_bound(ta,N,re[e].t); qsort(&ta[min],max-min+1,sizeof(ta[min]),cmp3); //对符合的任务进行排序...cmp3 con=0; if(re[e].k>=(max-min+1)) { for(a=min;a<(max+1);a++) if(ta[a].v>0)con=con+ta[a].v; //else接的是最近那if } else { int uo=0; for(a=min;uo<re[e].k && a<(max+1);a++) { if(ta[a].v>0) { uo++; con=con+ta[a].v; } //这里这里<0的时候a是不算的 所以要用另一个变量来算 } } printf("%d/n",con) ; } } return 0; } int cmp1( const void *a ,const void *b) //比较函数的函数体 { return (*(task *)a).x < (*(task *)b).x ? 1 : -1; } int cmp3( const void *a ,const void *b) //比较函数的函数体 { return (*(task *)a).v < (*(task *)b).v ? 1 : -1; } int lower_bound(struct task array[],int n,int b) { int left, right, middle; left = 0; right = n - 1; while (left < right) { middle = (left + right) / 2; if (array[middle].x > b) { right = middle; } else if(array[middle].x < b) { left = middle + 1; } else return middle; } return left; } int upper_bound(struct task array[], int n, int b) { int left, right, middle; left = 0; right = n - 1; while (left < right) { middle = (left + right) / 2; if (array[middle].x < b) { left = middle + 1; } else if(array[middle].x > b) { right = middle; } else return middle; } return left; }
是输出超限。。。。
越氏羿界 2014-04-18
  • 打赏
  • 举报
回复
[quote=引用 1 楼 FancyMouse 的回复:] 提示 已改,不过现在是输出朝鲜了。。。。这又是什么原因???? 源代码: #include<iostream> #include<cstdio> #include<algorithm> //qsort的头文件 #define H 10000 using namespace std; struct task { long x; long v; }; struct resume { long s,t; int k; }; int cmp1( const void *a ,const void *b); //比较函数 int cmp3( const void *a ,const void *b); int lower_bound(struct task array[],int n,int b) ; int upper_bound(struct task array[], int n, int b); int main() { int con,i,a; int e; struct task ta[H]; struct resume re[H]; int N,M; while(scanf("%d",&N)) { for(i=0;i<N;i++) //输入任务、新人 scanf("%ld%ld",&ta[i].x, &ta[i].v); scanf("%d",&M) ; for(i=0;i<M;i++) scanf("%ld%ld%d",&re[i].s, &re[i].t,&re[i].k); qsort(ta,N,sizeof(ta[0]),cmp1); //快速排序 for(e=0;e<M;e++) { int min,max; qsort(ta,N,sizeof(ta[0]),cmp1); //快速排序 min=lower_bound(ta,N,re[e].s); max=upper_bound(ta,N,re[e].t); qsort(&ta[min],max-min+1,sizeof(ta[min]),cmp3); //对符合的任务进行排序...cmp3 con=0; if(re[e].k>=(max-min+1)) { for(a=min;a<(max+1);a++) if(ta[a].v>0)con=con+ta[a].v; //else接的是最近那if } else { int uo=0; for(a=min;uo<re[e].k && a<(max+1);a++) { if(ta[a].v>0) { uo++; con=con+ta[a].v; } //这里这里<0的时候a是不算的 所以要用另一个变量来算 } } printf("%d/n",con) ; } } return 0; } int cmp1( const void *a ,const void *b) //比较函数的函数体 { return (*(task *)a).x < (*(task *)b).x ? 1 : -1; } int cmp3( const void *a ,const void *b) //比较函数的函数体 { return (*(task *)a).v < (*(task *)b).v ? 1 : -1; } int lower_bound(struct task array[],int n,int b) { int left, right, middle; left = 0; right = n - 1; while (left < right) { middle = (left + right) / 2; if (array[middle].x > b) { right = middle; } else if(array[middle].x < b) { left = middle + 1; } else return middle; } return left; } int upper_bound(struct task array[], int n, int b) { int left, right, middle; left = 0; right = n - 1; while (left < right) { middle = (left + right) / 2; if (array[middle].x < b) { left = middle + 1; } else if(array[middle].x > b) { right = middle; } else return middle; } return left; }
越氏羿界 2014-04-18
  • 打赏
  • 举报
回复
引用 1 楼 FancyMouse 的回复:
提示 由于数据量较大,推荐使用scanf/printf。
为什么用这两个会 减少数据量呢?????
FancyMouse 2014-04-18
  • 打赏
  • 举报
回复
引用 2 楼 u014772810 的回复:
[quote=引用 1 楼 FancyMouse 的回复:] 提示 由于数据量较大,推荐使用scanf/printf。
即是说,把现在程序里面的输入输出流全都改为scanf、和printf 即可?????[/quote] 不保证。我还没仔细看你代码。你先改了再说。
越氏羿界 2014-04-18
  • 打赏
  • 举报
回复
引用 1 楼 FancyMouse 的回复:
提示 由于数据量较大,推荐使用scanf/printf。
即是说,把现在程序里面的输入输出流全都改为scanf、和printf 即可?????
FancyMouse 2014-04-18
  • 打赏
  • 举报
回复
提示 由于数据量较大,推荐使用scanf/printf。
lm_whales 2014-04-18
  • 打赏
  • 举报
回复
1)输入时剔除贡献值非正的数据。数据量减小到 n = N - nn ==> O(N) ,nn 表示贡献值非正的数据个数。 2)对所有数据的难度快排。O( nlogn) 3)对每个新生,难度符合要求的数据,按照贡献度 快选,或者计数排序。 O(n)*M 输入 scanf,-->还可以改为从文件输入。 输出 printf -->还可以改为输出到文件。

65,209

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧