zoukankan      html  css  js  c++  java
  • POJ3171 Cleaning Shifts DP,区间覆盖最值

            题目大意。N个区间覆盖[T1,T2]及相应的代价S,求从区间M到E的所有覆盖的最小代价是多少。

     (1 <= N <= 10,000)。(0 <= M <= E <= 86,399).

          思路是DP,首先将每一个区间依照T2从小到大排序,设dp(k)为从m覆盖到k所需最小代价,则有

    dp(T2[i]) = min(dp(T2[i]), {dp(j) + Si,  T1[i] - 1<=j <= T2[i]}),对于 {dp(j) + Si,  T1[i] - 1<=j <= T2[i]}我们能够用线段树来进行优化,所以终于复杂度为O(n*logE)。

    #include <stdio.h>
    #include <vector>
    #include <math.h>
    #include <string.h>
    #include <string>
    #include <iostream>
    #include <queue>
    #include <list>
    #include <algorithm>
    #include <stack>
    #include <map>
    #include <time.h>
    using namespace std;
    
    struct T
    {
    	int t1;
    	int t2;
    	int S;
    };
    #define MAXV 5000000001
    long long BinTree[270000];
    T cows[10001];
    long long DP[86401];
    
    template<class TYPE>
    void UpdateValue(TYPE st[],int i, TYPE value, int N, bool bMin)
    {
    	i += N - 1;
    	st[i] = value;
    	while (i > 0)
    	{
    		i = (i - 1) / 2;
    		if (bMin)
    		{
    			st[i] = min(st[i * 2 + 1], st[i * 2 + 2]);
    		}
    		else
    			st[i] = max(st[i * 2 + 1], st[i * 2 + 2]);
    	}
    }
    
    template<class TYPE>
    TYPE QueryST(TYPE st[], int a, int b, int l, int r, int k, bool bMin)
    {
    	if (l > b || a > r)
    	{
    		return bMin ? MAXV : 0;
    	}
    	if (l >= a && b >= r)
    	{
    		return st[k];
    	}
    	else
    	{
    		TYPE value1 = QueryST(st, a, b, l, (r + l) / 2, k * 2 + 1, bMin);
    		TYPE value2 = QueryST(st, a, b, (r + l) / 2 + 1, r, k * 2 + 2, bMin);
    		if (bMin)
    		{
    			return min(value1, value2);
    		}
    		else
    		{
    			return max(value1, value2);
    		}
    	}
    }
    
    int compT(const void* a1, const void* a2)
    {
    	if (((T*)a1)->t2 - ((T*)a2)->t2 == 0)
    	{
    		return ((T*)a1)->t1 - ((T*)a2)->t1;
    	}
    	else
    		return ((T*)a1)->t2 - ((T*)a2)->t2;
    }
    
    
    int main()
    {
    #ifdef _DEBUG
    	freopen("e:\in.txt", "r", stdin);
    #endif
    	int N, M, E;
    	scanf("%d %d %d", &N, &M, &E);
    	M++;
    	E++;
    	for (int i = 0; i < N; i++)
    	{
    		scanf("%d %d %d", &cows[i].t1, &cows[i].t2, &cows[i].S);
    		cows[i].t1++;
    		cows[i].t2++;
    	}
    	int maxe = 1;
    	while (maxe < E)
    	{
    		maxe *= 2;
    	}
    	for (int i = 0; i < maxe * 2;i++)
    	{
    		BinTree[i] = MAXV;
    	}
    	for (int i = 0; i <= E;i++)
    	{
    		DP[i] = MAXV;
    	}
    
    	DP[M - 1] = 0;
    	UpdateValue<long long>(BinTree, M - 1, 0, maxe, true);
    	qsort(cows, N, sizeof(T), compT);
    	for (int i = 0; i < N;i++)
    	{
    		DP[cows[i].t2] = min(DP[cows[i].t2], QueryST<long long>(BinTree, cows[i].t1 - 1, cows[i].t2, 0, maxe - 1, 0, true) + cows[i].S);
    		UpdateValue<long long>(BinTree, cows[i].t2, DP[cows[i].t2], maxe, true);
    	}
    	if (E <= cows[N - 1].t2)
    	{
    		DP[E] = QueryST<long long>(BinTree, E, cows[N - 1].t2, 0, maxe - 1, 0, true);
    	}
    	
    	if (DP[E] >= MAXV)
    	{
    		printf("-1
    ");
    	}
    	else
    		printf("%I64d
    ", DP[E]);
    	return 0;
    }



  • 相关阅读:
    「UVA12293」 Box Game
    「CF803C」 Maximal GCD
    「CF525D」Arthur and Walls
    「CF442C」 Artem and Array
    LeetCode lcci 16.03 交点
    LeetCode 1305 两棵二叉搜索树中的所有元素
    LeetCode 1040 移动石子直到连续 II
    LeetCode 664 奇怪的打印机
    iOS UIPageViewController系统方法崩溃修复
    LeetCode 334 递增的三元子序列
  • 原文地址:https://www.cnblogs.com/gcczhongduan/p/5112678.html
Copyright © 2011-2022 走看看