zoukankan      html  css  js  c++  java
  • seq(2018.10.24)

    一道(dp)题。。。
    期望(40)分解法
    预处理:离散化,然后让连续一段值相同的元素合并为一个元素。
    正式(DP)
    显然有个最差策略为每个元素处都切一次,则切的次数为元素的个数(-1)
    相对地来说就是假设全部元素之间就已经切开,要尽量多地合并元素
    (DP)的第一维用来确认当前是合并了值为多少的两个数值段,DP的第二维来记住最后一次合并是合并了哪个位置的两个线段
    (DP[i][j]=)对于值为(1)(i+1)的数值段, 最后一次合并为合并(a[j])(a[j+1])这两个元素,最多能合并的总次数
    而相对应的转移方程就是:
    (DP[i][j] =max( DP[i-1][j']+1) (合并 a[j'] , a[j'+1] 不会与 合并a[j],a[j+1]冲突))
    冲突是指合并(a[i],a[i+1])的同时也合并(a[j],a[j+1])会导致无法拼接成单调不降的序列,其充要条件是(i+1=j)且值为(a[i+1])的数值段在原序列中出现了不止(1)次,

    空间和时间复杂度都是(O(n^2)),期望得分(40)

    期望(100)分解法
    优化:
    (1.)滚动数组优化空间为(O(n))
    (2.)因为对于每个(i=x),转移的时候只用考虑最大值和次大值,如果最大值和当前状态冲突,则用次大值更新

    空间和时间复杂度都是(O(n)),期望得分(100)

    #include<cstdio>
    #include<algorithm>
    #include<map>
    using namespace std;
    int n,a[100001],cnt,b[100001],tot,pre[100001],nxt[100001],h[100001],deg[100001];
    pair<int,int>dp[2],DP[2];
    map<int,int>mp;
    void add(int x,int y){pre[++cnt]=y;nxt[cnt]=h[x];h[x]=cnt;deg[x]++;}
    int main()
    {
    	scanf("%d",&n);
    	for(int i=1;i<=n;i++)scanf("%d",&a[i]),b[i]=a[i];
    	sort(b+1,b+n+1);
    	for(int i=1;i<=n;i++)if(!mp[b[i]])mp[b[i]]=++tot;
    	for(int i=1;i<=n;i++)a[i]=mp[a[i]];tot=0;
    	for(int i=1;i<=n;i++)if(a[i]!=a[i+1])a[++tot]=a[i];
    	for(int i=1;i<=tot;i++)add(a[i],i);
    	for(int i=h[1];i;i=nxt[i])
    		if(a[pre[i]+1]==2)
    		{
    			dp[1]=max(dp[1],make_pair(1,pre[i]));
    			if(dp[1]>DP[1])swap(dp[1],DP[1]);
    		}
    	for(int i=2;i<cnt;i++)
    	{
    		dp[i&1]=dp[(i&1)^1];DP[i&1]=DP[(i&1)^1];
    		for(int j=h[i];j;j=nxt[j])
    			if(a[pre[j]+1]==a[pre[j]]+1)
    			{
    				if(DP[(i&1)^1].second+1!=pre[j]||deg[i]==1)dp[i&1]=max(dp[i&1],make_pair(DP[(i&1)^1].first+1,pre[j]));
    				else dp[i&1]=max(dp[i&1],make_pair(dp[(i&1)^1].first+1,pre[j]));
    				if(dp[i&1]>DP[i&1])swap(dp[i&1],DP[i&1]);
    			}
    	}
    	printf("%d
    ",tot-1-DP[(cnt-1)&1].first);
    }
    
  • 相关阅读:
    母牛的故事
    python 实现计算数独
    java程序计算数独游戏
    《深入理解Java虚拟机》笔记7
    安装red5 1.0.1版本Java_home不能用Java7
    计算流图中的循环集合
    《深入理解Java虚拟机》笔记5
    《深入理解Java虚拟机》笔记4
    n的阶乘-编程2.md
    爬楼梯问题-斐波那契序列的应用.md
  • 原文地址:https://www.cnblogs.com/lcxer/p/9846216.html
Copyright © 2011-2022 走看看