zoukankan      html  css  js  c++  java
  • CF833B The Bakery

    此题可用决策单调性来做

    证明 略

    引入

    决策单调性((My blog))

    思路

    于是此题便可先用分治优化决策单调性

    时间 (O(n^2*k)) (101 tests) 中 只能过前(9)(9pts) ?

    #include <map>
    #include <string>
    #include <cstdio>
    #include <string>
    #include <cstdlib>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    #define reg register int
    #define isdigit(x) ('0' <= x&&x <= '9')
    template<typename T>
    inline T Read(T Type)
    {
    	T x = 0,f = 1;
    	char a = getchar();
    	while(!isdigit(a)) {if(a == '-') f = -1;a = getchar();}
    	while(isdigit(a)) {x = (x << 1) + (x << 3) + (a ^ '0');a = getchar();}
    	return x * f;
    }
    const int MAXN = 35010,inf = MAXN;
    int a[MAXN],dp[MAXN][55];
    bool vis[MAXN];
    inline int cost(int l,int r)
    {
    	int res = 0;
    	for(reg i = l;i <= r;i++)
    	{
    		if(!vis[a[i]]) res++;
    		vis[a[i]] = 1;
    	}
    	for(reg i = 1;i <= r;i++) vis[a[i]] = 0;	
    	return res;
    }
    inline void dfs(int k,int l,int r,int opl,int opr)
    {
    	if(l > r) return;
    	int mid = l + r >> 1,maxl = -inf,id;
    	for(reg i = opl;i <= min(opr,mid);i++)
    	{
    		int cur = dp[i - 1][k - 1] + cost(i,mid);
    		if(cur > maxl) maxl = cur,id = i;
    	}
    	dp[mid][k] = maxl;
    	dfs(k,l,mid - 1,opl,id);
    	dfs(k,mid + 1,r,id,opr);
    }
    int main()
    {
    	int n = Read(1),k = Read(1);
    	for(reg i = 1;i <= n;i++)
    		a[i] = Read(1);
    	for(reg i = 1;i <= k;i++) dfs(i,1,n,1,n);
    	printf("%d
    ",dp[n][k]);
    	return 0;
    }
    

    考虑优化

    观察代码 发现(cost)(查询区间不同数个数)就有一层(n)

    考虑降成(O(1)) 但预处理是(O(n^2))

    于是只能降成(O(log_2^n))

    从我们学习的数据结构中寻找

    发现主席树恰好可以胜任

    用主席树(A)掉这道题

    SP3267 DQUERY - D-query

    再粘过来就行了

    然而我这道题写的莫队 现在又写了一遍主席树 233

    (Code)

    时间复杂度 (O(n*log_2^n*k))

    #include <map>
    #include <string>
    #include <cstdio>
    #include <string>
    #include <cstdlib>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    #define reg register int
    #define isdigit(x) ('0' <= x&&x <= '9')
    template<typename T>
    inline T Read(T Type)
    {
    	T x = 0,f = 1;
    	char a = getchar();
    	while(!isdigit(a)) {if(a == '-') f = -1;a = getchar();}
    	while(isdigit(a)) {x = (x << 1) + (x << 3) + (a ^ '0');a = getchar();}
    	return x * f;
    }
    const int MAXN = 35010,inf = MAXN;
    int a[MAXN],dp[MAXN][55],n,k;
    namespace segment_tree
    {
    	struct node
    	{
    		int l,r,val;
    	}tree[MAXN * 40];
    	map<int,int> vis;
    	int cnt,root[MAXN];
    	inline int update(int k,int l,int r,int pos,int v)
    	{
    	    tree[++cnt] = tree[k],tree[cnt].val += v;
    	    k = cnt;
    	    if(l == r) return k;
    	    int mid = l + r >> 1;
    	    if(pos <= mid) tree[k].l = update(tree[k].l,l,mid,pos,v);
    	    else tree[k].r = update(tree[k].r,mid + 1,r,pos,v);
    	    return k;
    	}
    	inline int query(int k,int pos,int l,int r)
    	{
    	    if(l >= pos) return tree[k].val;
    	    int mid = l + r >> 1;
    	    if(pos <= mid) return query(tree[k].l,pos,l,mid) + tree[tree[k].r].val;
    	    return query(tree[k].r,pos,mid + 1,r);
    	}
    	inline void init()
    	{
    		n = Read(1),k = Read(1);
    		root[0] = tree[0].l = tree[0].r = tree[0].val = 0;
    		for(reg i = 1;i <= n;i++)
    		{
    			int x = Read(1);
    			if(!vis[x]) root[i] = update(root[i - 1],1,n,i,1);
    			else {
    				int k = update(root[i - 1],1,n,vis[x],-1);
    				root[i] = update(k,1,n,i,1);
    			}
    			vis[x] = i;
    		}
    	}
    }
    using namespace segment_tree;
    inline int cost(int l,int r) {return query(root[r],l,1,n);}
    inline void dfs(int k,int l,int r,int opl,int opr)
    {
    	if(l > r) return;
    	int mid = l + r >> 1,maxl = -inf,id;
    	for(reg i = opl;i <= min(opr,mid);i++)
    	{
    		int cur = dp[i - 1][k - 1] + cost(i,mid);
    		if(cur > maxl) maxl = cur,id = i;
    	}
    	dp[mid][k] = maxl;
    	dfs(k,l,mid - 1,opl,id);
    	dfs(k,mid + 1,r,id,opr);
    }
    int main()
    {
    	init();
    	for(reg i = 1;i <= k;i++) dfs(i,1,n,1,n);
    	printf("%d
    ",dp[n][k]);
    	return 0;
    }
    
  • 相关阅读:
    Flask---框架入门
    续--Flask, Django
    测试开发中Django和Flask框架
    oracle数据库的存储原理
    Oracle 存储过程—为数传递变量
    Oracle scope中 spfile、memory、both 的区别
    数据库性能衡量指标
    raid卷性能测试
    HTTP POST请求报文格式分析与Java实现文件上传
    使用Navicat 导入导出Mysql数据库
  • 原文地址:https://www.cnblogs.com/resftlmuttmotw/p/12016165.html
Copyright © 2011-2022 走看看