zoukankan      html  css  js  c++  java
  • A Twisty Movement题解

    这题又开阔了我的眼界
    不考虑翻转这个条件,a[i]只有1和2时,就很是快乐
    最长不下降子序列肯定长这样
    (11……22……)
    我们处理一下,把1和2放在两组中
    ([11……][22……])
    定义 (f[i][j]) (j为1或2)为前i个点,第i个点属于第j组

    [f[i][1]=f[i-1][j]+(a[i]==1) ]

    [f[i][2]=max(f[i-1][1],f[i-1][2]+(a[i]==2)) ]

    考虑一下翻转,比如
    (1112212211212222)
    它翻转后的最长不下降子序列是
    (11111122222222)
    (翻转区间 (4、12)
    要是我们翻转回来,这个序列就变成了
    (11122221112222)
    发现它可以分为4组
    ([111][2222][111][2222]) (毕竟这样的话交换23区间就变成了上面的情况了)
    所以就可以列出方程

    [f[i][1]=f[i-1][1]+(a[i]==1) ]

    [f[i][2]=max(f[i-1][1],f[i-1][2]+(a[i]==2) ]

    [f[i][3]=max(f[i-1][2],f[i-1][3]+(a[i]==1) ]

    [f[i][4]=max(f[i-1][3],f[i-1][4]+(a[i]==2) ]

    然后我们压掉第一维就可
    提供一个理解思路(以 (f[i][2]) 为例)
    1.从 (f[i-1][1]) 转移:开启一个新的组
    2.从 (f[i-][2]) 转移:往已经开启的组添加一个数

    #include<iostream>
    #include<cstdio>
    #define ll long long
    using namespace std;
    ll n,m,f[10],ans;
    
    int main(){
    	scanf("%lld",&n);
    	for(ll i=1;i<=n;i++){
    		ll a1;
    		scanf("%lld",&a1);
    		f[1]+=(a1==1);
    		f[2]=max(f[1],f[2]+(a1==2));
    		f[3]=max(f[2],f[3]+(a1==1));
    		f[4]=max(f[3],f[4]+(a1==2));
    	}
    	cout<<f[4];
    }
    
  • 相关阅读:
    结构型模式上
    创建型模式下
    创建型模式中
    创建型模式上
    设计模式总述
    Java中事件机制
    UI常用控件
    UITextField和UIViewConteoller
    UIScrollView 和 UIPageControl
    分栏视图控制器
  • 原文地址:https://www.cnblogs.com/caijiLYC/p/13441643.html
Copyright © 2011-2022 走看看