ACM: LA 4254 记住…
2016-05-19 23:27
411 查看
题目略;
题意: 现在又n个任务, 每个任务有一个时间段可以执行和它需要的量--> [ri, di,
wi]; 现在要求你
每个任务是可以中断的(即: 执行一段时间可以停止, 再后面某个时间再继续执行剩下的时间),
全部任务完毕, cpu的最大速度中的最小值. (速度: wi/执行时间).
解题思路:
1.
我每次都不记得, 最大值中求最小的问题用二分方法可以求, 自我检讨.
2.
用二分的方法枚举速度, 这样问题就可以转换成, 已知速度, 判断是否可以完成全部任务,
这里需要用贪心的方法, 在一段时间内尽可能的完成多的任务, 所以每次我们选取执行完毕
时间早的任务先做, 直到cpu不休息或者没有任务需要在这段时间做的.
3.
在每次查找时间最早完成的任务, 可以使用线段是的方法O(logn)效率还行.
代码:
#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
#define MAX 10010
const int INF = (1<<29);
struct node
{
int r, d, w;
}a[MAX];
int n, D;
int pt[4*MAX], di[2*MAX];
int timew[MAX];
bool cmp(const int &x, const int
&y) //根据时间从小到大排序
{
int tx = x > 0 ? a[x].r :
a[-x].d;
int ty = y > 0 ? a[y].r :
a[-y].d;
return tx < ty;
}
inline void update(int i) //维护线段树
{
while(i^1) //i != 1
{
pt[i>>1]
= a[ pt[i] ].d < a[ pt[i^1] ].d ?
pt[i] : pt[i^1];
i
>>= 1;
}
}
inline int getTime(int i)
{
return i > 0 ? a[i].r :
a[-i].d;
}
bool judge(int m)
{
for(int i = 1; i <= n; ++i)
timew[i] = a[i].w;
di[2*n] = di[2*n-1];
for(int i = 0; i < 2*n; ++i)
{
if(di[i] >
0)
{
pt[ D+di[i] ]
= di[i];
update(D+di[i]);
}
else
{
pt[ D-di[i] ]
= 0;
update(D-di[i]);
}
long long use = (long long)m*(
getTime(di[i+1]) - getTime(di[i]) );
while(use)
{
int id =
pt[1];
if(id == 0)
break;
if(use
>= timew[id])
{
use
-= timew[id];
timew[id]
= 0;
pt[D+id]
= 0;
update(D+id);
}
else
{
timew[id]
-= use;
use
= 0;
}
}
}
for(int i = 1; i <= n; ++i)
if(timew[i] != 0)
return
false;
return true;
}
int main()
{
// freopen("input.txt", "r", stdin);
int caseNum;
scanf("%d", &caseNum);
while(caseNum--)
{
scanf("%d",
&n);
for(int i = 1; i
<= n; ++i)
{
scanf("%d %d
%d", &a[i].r, &a[i].d,
&a[i].w);
di[2*i-2] =
i;
di[2*i-1] =
-i;
}
sort(di, di+2*n, cmp);
for(D = 1; D <
n+2; D <<= 1);
memset(pt, 0,
sizeof(pt[0])*2*D);
a[0].d = INF;
int left = 0, right =
1000*1000+5;
int mid;
while(true)
{
mid =
(left+right)/2;
if(mid ==
left) break;
if(judge(mid))
right = mid;
else left =
mid;
}
printf("%d\n", mid+1);
}
return 0;
}
题意: 现在又n个任务, 每个任务有一个时间段可以执行和它需要的量--> [ri, di,
wi]; 现在要求你
每个任务是可以中断的(即: 执行一段时间可以停止, 再后面某个时间再继续执行剩下的时间),
全部任务完毕, cpu的最大速度中的最小值. (速度: wi/执行时间).
解题思路:
1.
我每次都不记得, 最大值中求最小的问题用二分方法可以求, 自我检讨.
2.
用二分的方法枚举速度, 这样问题就可以转换成, 已知速度, 判断是否可以完成全部任务,
这里需要用贪心的方法, 在一段时间内尽可能的完成多的任务, 所以每次我们选取执行完毕
时间早的任务先做, 直到cpu不休息或者没有任务需要在这段时间做的.
3.
在每次查找时间最早完成的任务, 可以使用线段是的方法O(logn)效率还行.
代码:
#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
#define MAX 10010
const int INF = (1<<29);
struct node
{
int r, d, w;
}a[MAX];
int n, D;
int pt[4*MAX], di[2*MAX];
int timew[MAX];
bool cmp(const int &x, const int
&y) //根据时间从小到大排序
{
int tx = x > 0 ? a[x].r :
a[-x].d;
int ty = y > 0 ? a[y].r :
a[-y].d;
return tx < ty;
}
inline void update(int i) //维护线段树
{
while(i^1) //i != 1
{
pt[i>>1]
= a[ pt[i] ].d < a[ pt[i^1] ].d ?
pt[i] : pt[i^1];
i
>>= 1;
}
}
inline int getTime(int i)
{
return i > 0 ? a[i].r :
a[-i].d;
}
bool judge(int m)
{
for(int i = 1; i <= n; ++i)
timew[i] = a[i].w;
di[2*n] = di[2*n-1];
for(int i = 0; i < 2*n; ++i)
{
if(di[i] >
0)
{
pt[ D+di[i] ]
= di[i];
update(D+di[i]);
}
else
{
pt[ D-di[i] ]
= 0;
update(D-di[i]);
}
long long use = (long long)m*(
getTime(di[i+1]) - getTime(di[i]) );
while(use)
{
int id =
pt[1];
if(id == 0)
break;
if(use
>= timew[id])
{
use
-= timew[id];
timew[id]
= 0;
pt[D+id]
= 0;
update(D+id);
}
else
{
timew[id]
-= use;
use
= 0;
}
}
}
for(int i = 1; i <= n; ++i)
if(timew[i] != 0)
return
false;
return true;
}
int main()
{
// freopen("input.txt", "r", stdin);
int caseNum;
scanf("%d", &caseNum);
while(caseNum--)
{
scanf("%d",
&n);
for(int i = 1; i
<= n; ++i)
{
scanf("%d %d
%d", &a[i].r, &a[i].d,
&a[i].w);
di[2*i-2] =
i;
di[2*i-1] =
-i;
}
sort(di, di+2*n, cmp);
for(D = 1; D <
n+2; D <<= 1);
memset(pt, 0,
sizeof(pt[0])*2*D);
a[0].d = INF;
int left = 0, right =
1000*1000+5;
int mid;
while(true)
{
mid =
(left+right)/2;
if(mid ==
left) break;
if(judge(mid))
right = mid;
else left =
mid;
}
printf("%d\n", mid+1);
}
return 0;
}
相关文章推荐
- ACM: uva 10382
- ACM: 动态规划题 LA 4794
- ACM: 动态规划题 LA 3983
- ACM: 动态规划题 bnu 13149
- ACM: 动态规划题 uva 11825
- ACM: poj 1903
- ACM: uva_10755
- ACM: poj 3141
- Android五种储存方式—sqlite数据库存储
- ACM: poj 1964
- ACM: uva 3902
- 基于CXF Servlet方式发布Restful的Web服务(入门篇)
- ACM: 二分题 poj 3497
- ACM: uva 11210 &n…
- ACM: 暴力题 poj 2741
- ACM: uva 11464
- ACM: zoj 2714
- ACM: 贪心题 uva 11729
- ACM: 简单题 uva 10881
- ACM: 数学题 uva 11300