zoukankan      html  css  js  c++  java
  • [POI2015]MYJ

    [POI2015]MYJ


    这道题就是告诉你有(m)个条件,满足其中的一些条件(即一个区间找到的最小值小于等于该数则累加该最小值到最终的答案),使得最终的答案最大。另外最大值给出具体方案。


    那么,我们考虑DP做法:

    维护一个(dp[l,r,val])代表([l,r])中最小值是(val)的最优解(最大值)。

    有:

    [dp[l,r,val]=max(max(dp[l,pos-1,val~val_{limit}])+max(dp[pos+1,r,val~val_{limit}])+cnt[val,pos]*val) ]

    具体:就是枚举该区间所有可能的最小值,然后枚举最小值出现的位置(注意:如果一个位置是最小值了,那么其他位置只能是不少于最小值的数),对于所有在([l,r])区间的条件,过该最小值且条件的权值不少于最小值,那么,该条件就累加到(dp[l,r,val])贡献当中去。而我们还需要统计的是有(cnt[val,pos])个满足条件的区间。

    那么(max(dp[l,pos-1,val,val_{limit}]))怎么办?考虑到决策转移集合只增不减,我们考虑维护一个数组或变量优化。

    所以,我们可以不妨预处理出所有的值:(cnt[l,r,val,pos]),指的是在区间([l,r])中,最小值为(val),位置为(pos)(如果有多个位置满足则任选一个即可)条件的个数。

    由于(m)很小,所以我们直接枚举即可。

    最后按照方程递推。


    具体方案咋办呢?

    我们不妨记录每一个状态下去的最优值的最小值、和最小值所在位置,递归下去即可。

    我们可以在统计(dp[])过程中完成记录。


    但是(cnt[l,r,val,pos])空间开不下,那么只能现用现场计算啦!


    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<cmath>
    
    #define Re register
    #define CLR(x, y) memset(x,y,sizeof(x))
    #define FOR(i, x, y) for(Re int i=x;i<=y;++i)
    #define ROF(i, x, y) for(Re int i=x;i>=y;--i)
    
    using namespace std;
    
    const int MAXN = 55, MAXM = 4000 + 10, INF = 1 << 30;
    
    template <typename T> void read(T &x)
    {
    	bool mark = false;
    	char ch = getchar();
    	for(; ch < '0' || ch > '9'; ch = getchar()) if(ch == '-') mark = true;
    	for(x = 0; ch >= '0' && ch <= '9'; ch = getchar()) x = (x << 3) + (x << 1) + ch - '0';
    	if(mark) x = -x;
    	return;
    }
    
    /*
    
    dp[l, r, val] -> while the [l, r] minimum number is val, the optimal value(maximum) you can get
    cnt[val, pos] -> calculate this while computing dp[l, r, val].
    					[l, r] the valid number in this interval.
    f[l, r, val] -> max{dp[l, r, val ~ val_limit]}
    
    vmax[l, r, val] -> the val which f[l, r, val] get the maximum number, core[l, r, val] -> the position where dp[l, r, val] get the best results
    */
    
    int n, m, tot = 0, a[MAXM], b[MAXM], c[MAXM], table[MAXM];
    int dp[MAXN][MAXN][MAXM] = {}, cnt[MAXM][MAXN] = {}, f[MAXN][MAXN][MAXM] = {};
    int vmax[MAXN][MAXN][MAXM], core[MAXN][MAXN][MAXM];
    
    void discrete()
    {
    	sort(table + 1, table + m + 1);
    	tot = unique(table + 1, table + m + 1) - table - 1;
    	return;
    }
    int query(int x)
    {
    	int L = 1, R = tot, mid; 
    	while(L < R)
    	{
    		mid = L + ((R - L) >> 1);
    		if(table[mid] < x) L = mid + 1;
    		else R = mid;
    	}
    	return L;
    }
    void dfs(int l, int r, int k)
    {
    	if(l > r) return;
    	int pos = core[l][r][k], L = pos - 1, R = pos + 1;
    	dfs(l, L, vmax[l][L][k]);
    	printf("%d ", table[k]);
    	dfs(R, r, vmax[R][r][k]);
    	return;
    }
    int main()
    {
    	read(n), read(m);
    	FOR(i, 1, m) 
    	{
    		read(a[i]), read(b[i]), read(c[i]);
    		table[i] = c[i];
    	}
    	discrete();
    	FOR(i, 1, m) c[i] = query(c[i]);
    	FOR(len, 1, n)
    	{
    		for(Re int l = 1, r = len; r <= n; ++ l, ++ r)
    		{
    			// computing dp[l, r, val]
    			// prework:
    			CLR(cnt, 0);
    			FOR(i, 1, m)
    			{
    				if(a[i] >= l && b[i] <= r) 
    					FOR(j, a[i], b[i]) ++ cnt[c[i]][j];
    			}
    			ROF(i, tot - 1, 1)
    				FOR(j, l, r)
    					cnt[i][j] += cnt[i + 1][j];
    			
    			// now display the process of working out the main issues
    			ROF(val, tot, 1)
    			{
    				int &ans = dp[l][r][val];
    				FOR(pos, l, r)
    				{
    					int can = f[l][pos - 1][val] + f[pos + 1][r][val] + cnt[val][pos] * table[val];//can -> candidate
    					if(can >= ans) ans = can, core[l][r][val] = pos;
    				}
    				if(ans < f[l][r][val + 1]) f[l][r][val] = f[l][r][val + 1], vmax[l][r][val] = vmax[l][r][val + 1];
    				else f[l][r][val] = ans, vmax[l][r][val] = val;
    			}
    		}
    	}
    	printf("%d
    ", f[1][n][1]);
    	dfs(1, n, vmax[1][n][1]);
    	return 0;
    }
    
  • 相关阅读:
    Scala的基本类型和操作
    spark-submit部署应用的相关参数详解
    Spark的相关概念说明和检查点机制
    解决网站需要cookies登录和内容需要动态加载问题
    python 多线程
    re
    echarts中的图表大小自适应
    git过滤提交文件
    响应式媒体
    爬过的坑
  • 原文地址:https://www.cnblogs.com/zach20040914/p/14286891.html
Copyright © 2011-2022 走看看