标签:
题意:在给予的N个时间里,奶牛Bessie在M个时间段里进行产奶,但是每次产奶后都要休息R个时间
M个时间段里,分别有开始时间start和结束时间end,和该时间段里产奶的效率efficiency
求问,应该如何选择哪些时间段进行产奶,才能使得效率最大化
我的错误做法:设D[i]为到时间i以内,所能够产奶的最大量,从而d[i] = max(d[i-1], d[st[k]]+ef[k]);
最终还是TLE了,由于N最大为1000000,且k最大为1000,所以综合还是太花费时间了
正确思路:我看到了网上说最大递增子序列,立刻就明白了...之前的方法确实太复杂了,用最大递增子序列的方法
只用快排对M个时间段以结束时间从小到大排序,接着用到最大递增子序列的思路就进行解答。
由于M最大为1000,显然这个算法复杂度降低了好多。
AC代码:
#include <cstdio>
#include <algorithm>
using namespace std;
const int N = 1000005;
const int M = 1005;
int m,n,r,d[M];
struct node
{
int st,ed,ef;
}w[M];
int cmp(node n1, node n2)
{
return n1.ed < n2.ed;
}
void solve()
{
int ans = 0;
sort(w+1,w+m+1,cmp);
d[0] = 0;
for(int i = 1; i <= m; i++)
{
int mx = 0;
for(int j = 1; j < i; j++)
{
if(w[j].ed <= w[i].st) mx = max(mx, d[j]);
}
d[i] = mx+w[i].ef;
ans = max(ans,d[i]);
}
printf("%d\n", ans);
}
int main()
{
while(~scanf("%d %d %d", &n, &m, &r))
{
for(int i = 1; i <= m; i++)
{
scanf("%d %d %d",&w[i].st,&w[i].ed,&w[i].ef);
w[i].ed += r;
}
solve();
}
return 0;
}
TLE代码:
#include <cstdio>
#include <algorithm>
using namespace std;
const int N = 1000005;
const int M = 1005;
int n,m,r,len;
int st[M],ed[M],ef[M];
int d[N];
void solve()
{
d[0] = 0;
for(int i = 1; i <= n; i++)
{
int mx = 0;
for(int j = 0; j<m; j++)
{
if(i < ed[j] || i < st[j]) continue;
mx = max(mx, d[st[j]]+ef[j]);
}
d[i] = max(d[i-1], mx);
}
printf("%d\n", d[n]);
}
int main()
{
while(~scanf("%d %d %d", &n, &m, &r))
{
len = 0;
for(int i = 0; i < m; i++)
{
scanf("%d %d %d",st+i,ed+i,ef+i);
st[i] = max(0, st[i]-r);
}
solve();
}
return 0;
}
标签:
原文地址:http://www.cnblogs.com/sevenun/p/5440292.html