• hihocoder #1609 : 数组分拆II(思维)


    题目链接:http://hihocoder.com/problemset/problem/1609

    题解:就先拿一个数组最多分成两部分来说吧

    8

    1 2 3 4 5 1 2 3

    显然 输出时2 3

    可以这样分(1 2 3( 4 5 )1 2 3)显然分要分在(^4^5^)“^”这3个地方也就是说如果设pre[i]表示i位置最前面能到哪个位置,dp[i]表示i这个位置最少能分成几组。

    那么ans[i]=Sum(ans[j] , (dp[j]=dp[i]-1 && j > pre[i]))那么就可以考虑前缀和。如果是单纯的求i的前缀没什么意义,可以考虑球sum[dp[i]]表示到i的位置长度为dp[i]

    的一共有几种分法。这样就可以方便求出Sum(ans[j] , (dp[j]=dp[i]-1 && j > pre[i]))

    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #define mod 1000000007
    using namespace std;
    const int M = 1e5 + 10;
    typedef long long ll;
    int a[M] , pre[M] , dp[M];
    ll ans[M] , sum[M];
    bool vis[M];
    int main() {
        int n;
        scanf("%d" , &n);
        for(int i = 0 ; i < n ; i++) {
            scanf("%d" , &a[i]);
        }
        memset(pre , -1 , sizeof(pre));
        memset(dp , -1 , sizeof(dp));
        memset(vis , false , sizeof(vis));
        int left = -1;
        for(int i = 0 ; i < n ; i++) {
            if(vis[a[i]]) {
                left++;
                while(a[i] != a[left]) {
                    vis[a[left]] = false;
                    left++;
                }
            }
            pre[i] = left;
            vis[a[i]] = true;
        }
        for(int i = 0 ; i < n ; i++) {
            if(pre[i] == -1) {
                dp[i] = 1;
            }
            else {
                if(dp[i] == -1) dp[i] = dp[pre[i]] + 1;
                else dp[i] = min(dp[i] , dp[pre[i]] + 1);
            }
        }
        for(int i = 0 ; i < n ; i++) {
            if(pre[i] == -1) {
                ans[i] = 1;
                sum[dp[i]] += ans[i];
                sum[dp[i]] %= mod;
            }
            else {
                for(int j = max(0 , pre[i - 1]) ; j < pre[i] ; j++) {
                    sum[dp[j]] -= ans[j];
                    sum[dp[j]] %= mod;
                }
                ans[i] += sum[dp[i] - 1];
                sum[dp[i]] += ans[i];
                sum[dp[i]] %= mod;
            }
        }
        printf("%d %lld
    " , dp[n - 1] , (ans[n - 1] + mod) % mod);
        return 0;
    }
  • 相关阅读:
    39岁了,我依旧要谈梦想
    ASP原码加密工具介绍
    extjs_07_combobox&amp;tree&amp;chart
    JS0基础学习笔记(1)
    AndroidUI组件之ActionBar
    Sourcetree 更新git账号密码
    iOS人脸识别核心代码(备用)
    ios 中的tintColor
    appStore上传苹果应用程序软件发布
    iOS9适配 之 关于info.plist 第三方登录 添加URL Schemes白名单
  • 原文地址:https://www.cnblogs.com/TnT2333333/p/7677192.html
Copyright © 2020-2023  润新知