• POJ 3616 Milking Time DP


    POJ 3616 Milking Time DP

    题意

    给个时间长度N,现在有M个工作时间段和每个时间段能完成的工作,一次只能做一个工作并且一旦开始做就要把它做完,要求选择的两个工作时间段之间至少相差R时间(中间需要休息嘛)求选择那些工作N时间内能完成的最大工作量。输出最大值。

    解题思路

    对于这种一个数据节点包含多个值得数据,我首先感觉需要进行排序,再加上是时间上进行优化,更加深了我得判断,奈何我得排序选择开始出错了,这里应该是按照工作结束的时间点来进行排序。

    之后(dp[i])表示从头开始取到第(i)段所获得的最大值,但是这里(dp[i])开始的值就是选择第(i)段,这里蕴含了一定选第(i)段。之后两层for循环,寻找(i)之前的某个段,在满足结束时间(+R)的条件下,小于等于第(i)段的开始时间,然后看是否能更新(dp[i])

    代码实现

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int maxn=1e6+7;
    const int maxm=1e3+7;
    struct node
    {
    	int L, R, w;
        //友元类型小于号运算符重载
    	friend bool operator <(const node a, const node b)
    	{
    		return a.R<b.R;	
    	}	
    }a[maxm]; 
    int dp[maxm];
    int n, m, r;
    int main()
    {
    	scanf("%d%d%d", &n, &m, &r);
    	for(int i=1; i<=m; i++)
    	{
    		scanf("%d%d%d", &a[i].L, &a[i].R, &a[i].w);	
    	}	
    	sort(a+1, a+m+1);
    	int ans=0;
    	for(int i=1; i<=m; i++)
    	{
    		dp[i]=a[i].w;
    		for(int j=0; j<i; j++)
    		{
    			if(a[j].R+r<=a[i].L)
    			{
    				dp[i]=max(dp[i], dp[j]+a[i].w);
    			}
    		}
    		ans=max(ans, dp[i]);
    	}
    	printf("%d
    ", ans);
    	return 0;
    }
    
    欢迎评论交流!
  • 相关阅读:
    线程&进程
    C#入门基础
    .Net GC垃圾收集机制(下)
    .Net GC垃圾收集机制(上)
    GAC的理解及其作用
    C# DES加密,KEY和IV不同设置的写法
    常见加密算法简析
    密码学
    数字签名是什么?(数字证书)
    加密算法和MD5等散列算法的区别
  • 原文地址:https://www.cnblogs.com/alking1001/p/11908811.html
Copyright © 2020-2023  润新知