1. 程式人生 > >bzoj [POI2015]Myjnie

bzoj [POI2015]Myjnie

mem std tin 一行 mark void 輸出 str print

[POI2015]Myjnie

Time Limit: 40 Sec Memory Limit: 256 MBSec Special Judge

Description

有n家洗車店從左往右排成一排,每家店都有一個正整數價格p[i]。
有m個人要來消費,第i個人會駛過第a[i]個開始一直到第b[i]個洗車店,且會選擇這些店中最便宜的一個進行一次消費。但是如果這個最便宜的價格大於c[i],那麽這個人就不洗車了。
請給每家店指定一個價格,使得所有人花的錢的總和最大。

Input

第一行包含兩個正整數n,m(1<=n<=50,1<=m<=4000)。
接下來m行,每行包含三個正整數a[i],b[i],ci

Output

第一行輸出一個正整數,即消費總額的最大值。
第二行輸出n個正整數,依次表示每家洗車店的價格p[i],要求1<=p[i]<=500000。
若有多組最優解,輸出任意一組。

Sample Input

7 5

1 4 7

3 7 13

5 6 20

6 7 1

1 2 5

Sample Output

43

5 5 13 13 20 20 13





這個區間dp有點東西。。。
離散化一下
f[l][r][t] 表示完全屬於區間的人中最小值剛好是t的最優貢獻。
g[l][r][t] 表示完全屬於區間的人中最小值大於等於t的最優貢獻。
然後你的轉移就成了枚舉最小值是哪個店。
f[l][r][t]=max(g[l][i-1][t]+g[i+1][r][t]+cost(i))

然而這個cost(i)有點尷尬。。。你可能還有有個預處理h[i][j]表示在處理當前這個dp區間的情況下,包含i這個位置的人且在最小值為j的情況下能給錢的人有多少個。。。
寫吧~


1 mol 亂七八糟的錯誤。。。。。調一萬年啊。。。。


#include<bits/stdc++.h>
using namespace std;
const int maxm = 4004;
struct lpl{
    int a, b, c;    
}ini[maxm];
struct lpd{
    int g, f, pos;
}dp[55][55][maxm];
int n, m, k, ans[55
], pl[maxm], nam[maxm], mark[500005], h[55][maxm]; inline bool cmp(lpl A, lpl B) {return A.b == B.b ? A.a < B.a : A.b < B.b;} inline void putit() { scanf("%d%d", &n, &m); for(int i = 1; i <= m; ++i) scanf("%d%d%d", &ini[i].a, &ini[i].b, &ini[i].c), pl[i] = ini[i].c; sort(ini + 1, ini + m + 1, cmp); sort(pl + 1, pl + m + 1); k = 0; for(int i = 1; i <= m; ++i) if(pl[i] != pl[i - 1]){ k++; nam[k] = pl[i]; mark[pl[i]] = k; } for(int i = 1; i <= m; ++i) ini[i].c = mark[ini[i].c]; } inline void workk() { for(int l = n; l >= 1; --l) for(int r = l; r <= n; ++r){ for(int i = l; i <= r; ++i) for(int j = 1; j <= k; ++j) h[i][j] = 0; for(int i = 1; i <= m && ini[i].b <= r; ++i){ if(ini[i].a < l) continue; for(int j = ini[i].a; j <= ini[i].b; ++j) h[j][ini[i].c]++; } for(int i = l; i <= r; ++i) for(int j = k - 1; j >= 1; --j) h[i][j] += h[i][j + 1]; for(int i = l; i <= r; ++i) for(int j = k; j >= 1; --j){ int tmp = dp[l][i - 1][j].g + dp[i + 1][r][j].g + h[i][j] * nam[j]; if(dp[l][r][j].f < tmp){ dp[l][r][j].f = tmp; dp[l][r][j].pos = i; } dp[l][r][j].g = max(dp[l][r][j].f, dp[l][r][j + 1].g); } } } void dfs(int l, int r, int t) { if(l > r) return; if(dp[l][r][t].g == 0){ for(int i = l; i <= r; ++i) ans[i] = nam[t]; return; } for(int i = t; i <= k; ++i){ if(dp[l][r][t].g == dp[l][r][i].f){ int now = dp[l][r][i].pos; ans[now] = nam[i]; dfs(l, now - 1, i); dfs(now + 1, r, i); break; } } } inline void print() { printf("%d\n", dp[1][n][1].g); dfs(1, n, 1); for(int i = 1; i <= n; ++i) printf("%d ", ans[i]); } int main() { putit(); workk(); print(); return 0; }

bzoj [POI2015]Myjnie