• POJ 1201 Intervals 差分约束,最短路,RE会报TLE 难度:1 差分约束背景知识需联想证明


    题目

    http://poj.org/problem?id=1201

    题意

    给你n个整数区间(5e4数量级),要求给出一个最小的整数集合,这个整数集合至少与第i个区间有ci个重合整数

    思路

    很裸的差分约束,若令dp[w]为在[0, w]中取多少个整数,明显dp[bi] - dp[ai-1] = ci。那么现在还缺乏能够灵活调控具体数字的其他约束。这里选择了0<=dp[i]-dp[i - 1] <=1。
    从一个非可行解出发,比如dp[w], w=[1, mx],这里mx是最大的区间右端点,那么明显求满足约束的最大对偶解就能确保其可行,对应可行解的最小解。

    感想

    1. 这道题RE会报TLE!之前把first[MAXL]写成了first[MAXN],怎么也找不出为什么别人的能过自己的TLE
    2. 一开始想成了01整数规划。看来要多理解差分约束相关的思路

    Code

    3596K 329MS

    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <queue>
    #include <assert.h>
    using namespace std;
    const int MAXN = 5e4;
    const int MAXL = 5e4 + 2;
    const int MAXE = MAXL * 3;
    int n, mx, mn;
    int a[MAXN];
    int b[MAXN];
    int c[MAXN];
    int e;
    int first[MAXL];
    int nxt[MAXE];
    int to[MAXE];
    int cost[MAXE];
    int dp[MAXL];
    bool used[MAXL];
    int que[MAXL];
    
    void addEdge(int f, int t, int c) {
    	nxt[e] = first[f];
    	to[e] = t;
    	cost[e] = c;
    	first[f] = e++;
    }
    
    int main() {
    	freopen("C:\Users\Iris\source\repos\Project1\input.txt", "r", stdin);
    	freopen("C:\Users\Iris\source\repos\Project1\out.txt", "w", stdout);
    	e = 0;
    	memset(first, -1, sizeof first);
    	mn = MAXL;
    	scanf("%d", &n);
    	for (int i = 0; i < n; i++){
    		scanf("%d%d%d", a + i, b + i, c + i);
    		a[i] ++;
    		b[i] ++;
    		mx = max(mx, b[i]);
    		mn = min(mn, a[i] - 1);
    		if(c[i] > 0)addEdge(b[i], a[i] - 1, c[i]);
    	}
    	for (int i = mn + 1; i <= mx; i++) {
    		addEdge(i - 1, i, -1);
    		addEdge(i, i - 1, 0);
    		dp[i] = -1e9;
    	}
    	int quewnum = 0;
    	int quernum = 0;
    	dp[mx] = 0;
    	used[mx] = true;
    	que[(quewnum++) % MAXL] = mx;
    	while (quernum < quewnum) {
    		int f = que[(quernum++) % MAXL];
    		used[f] = false;
    		for (int p = first[f]; p != -1; p = nxt[p]) {
    			int t = to[p];
    			int c = cost[p];
    			if (dp[t] < dp[f] + c) {
    				//printf("%d(dp: %d)->%d(dp:%d/%d) %d
    ", f, dp[f], t, dp[t], dp[f] + c, c);
    				dp[t] = dp[f] + c;
    				if (!used[t]) {
    					que[(quewnum++) % MAXL] = t;
    					used[t] = true;
    				}
    			}
    		}
    	}
    	printf("%d
    ", dp[mn]);
    	return 0;
    }
    
    
  • 相关阅读:
    数据挖掘相关资料收集(持续更新)
    常见面试之机器学习算法思想简单梳理
    在c中保存状态
    lua 和 c
    lua 基础库
    lua 面向对象
    lua 高级
    lua 基础
    lua中的协程
    cocos2d中的可见性检测
  • 原文地址:https://www.cnblogs.com/xuesu/p/14368371.html
Copyright © 2020-2023  润新知