日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

362. 区间

發布時間:2024/1/18 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 362. 区间 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

給定 n 個區間 [ai,bi] 和 n 個整數 ci。

你需要構造一個整數集合 Z,使得 ?i∈[1,n],Z 中滿足 ai≤x≤bi 的整數 x不少于 ci 個。

求這樣的整數集合 Z 最少包含多少個數。

輸入格式

第一行包含整數 n。

接下來 n行,每行包含三個整數 ai,bi,ci。

輸出格式

輸出一個整數表示結果。

數據范圍

1≤n≤50000,
0≤ai,bi≤50000,
1≤ci≤bi?ai+1

輸入樣例:

5 3 7 3 8 10 3 6 8 1 1 3 1 10 11 1

輸出樣例:

6

思路

/* 這一題是一定有解的,因為最壞的情況下我們可以把1~50000中的數據全部選上。 本次存在兩種做法:(1)貪心;(2)差分約束。下面使用差分約束解決這個問題。 這里可以使用前綴和的思想求解,因為前綴和中S[0]=0,所有這里將ai,bi所在的區間范圍加上一個1,區間范圍變成了[1, 50001],這樣并不影響最終的結果。 S[i]表示:前i個數中被選出數的個數。我們最終要求解的就是S50001的最小值,因此需要使用最長路徑。對于S,S需要滿足如下條件: (1)Si≥Si?1,1≤i≤50001; (2)Si?Si?1≤1?Si?1≥Si?1; (3)區間[a, b]中至少有c個數?Sb?Sa?1≥c?Sb≥Sa?1+c;需要驗證一下:從源點出發,是否一定可以走到所有的邊。根據條件(1),從i-1可以走到i,因此從0可以走到1,從1可以走到2,......,因此存在這樣的源點。*/

代碼:

#include <bits/stdc++.h> using namespace std; const int N = 5e4 + 10, M = 15e4 + 10; int dist[N], st[N]; int h[N], e[M], ne[M], w[M], idx; int n;void add(int a, int b, int c) {e[idx] = b;w[idx] = c;ne[idx] = h[a];h[a] = idx++; } void spfa() {memset(dist, -0x3f, sizeof(dist));dist[0] = 0;queue<int> qu;qu.push(0);st[0] = 1;while (qu.size()){int t = qu.front();qu.pop();st[t] = 0;for (int i = h[t]; i != -1; i = ne[i]){int j = e[i];if (dist[j] < dist[t] + w[i]){dist[j] = dist[t] + w[i];if (!st[j]){st[j] = 1;qu.push(j);}}}} } int main() {scanf("%d", &n);memset(h, -1, sizeof(h));for (int i = 1; i < N; i++){add(i - 1, i, 0);add(i, i - 1, -1);}for (int i = 0; i < n; i++){int a, b, c;scanf("%d %d %d", &a, &b, &c);a++, b++;add(a - 1, b, c);}spfa();printf("%d\n", dist[50001]);return 0; }

總結

以上是生活随笔為你收集整理的362. 区间的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。