zoukankan      html  css  js  c++  java
  • HDU 4455(dp)

    题意:给定一个序列ai,个数为n。再给出一系列w;对于每个w,求序列中,所有长度为w的连续子串中的权值和,子串权值为子串中不同数的个数。

    思路:动态规划,用dp[w]表示当前长度为w的时候的权值和。显然dp[1] = n; 如果求dp[2]的话,那么它可以由dp[1]推出来,首先它比dp[1]少了最后一个子序列,那么最后一个子序列的权值用num来表示,num[i]从后面开始数i位的权值,也就是不同的个数。然后在计算每个子序列多了一个多元素多增加的权值,这里用sum[i]表示长度两个相同元素最近距离大于等于i的总个数,关键是这个怎么求,那么我们还可以开一个辅助数组c, c[i]表示数组中两个相同的数最小距离为i的总个数。那么sum[i] = sum[i + 1] + c[i], 所以dp[i] = dp[i - 1] + sum[i] - num[i - 1];

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    const int maxn = 1000100;
    typedef long long ll;
    ll dp[maxn];
    int a[maxn];
    int c[maxn];
    int sum[maxn];
    int num[maxn];
    int pre[maxn];
    int main()
    {
        int n, q;
        while (~scanf("%d", &n) && n)
        {
            for (int i = 1; i <= n; i++)
                scanf("%d", &a[i]);
            memset(c, 0, sizeof(c));
            memset(pre, 0, sizeof(pre));
            for (int i = 1; i <= n; i++)
            {
                c[i - pre[a[i]]]++;
                pre[a[i]] = i;
            }
            sum[n] = c[n];
            for (int i = n - 1; i >= 1; i--)
                sum[i] = sum[i + 1] + c[i];
            memset(c, 0, sizeof(c));
            c[a[n]] = 1;
            num[1] = 1;
            for (int i = 2; i <= n; i++)
            {
                if (c[a[n - i + 1]])
                    num[i] = num[i - 1];
                else
                {
                    num[i] = num[i - 1] + 1;
                    c[a[n - i + 1]] = 1;
                }
            }
            dp[1] = n;
            for (int i = 2; i <= n; i++)
                dp[i] = dp[i - 1] + sum[i] - num[i - 1];
            scanf("%d", &q);
            int t;
            while (q--)
            {
                scanf("%d", &t);
                printf("%lld
    ", dp[t]);
            }
        }
        return 0;
    }
  • 相关阅读:
    Linux下c++使用pthread库
    一半,一绊
    【codevs3945】 完美拓印
    【poj2942】 Knights of the Round Table
    【bzoj2730】 HNOI2012—矿场搭建
    【poj1177】 Picture
    Tarjan学习笔记
    联赛总结
    【poj3461】 Oulipo
    【csuoj1014】 西湖三人行
  • 原文地址:https://www.cnblogs.com/Howe-Young/p/4903797.html
Copyright © 2011-2022 走看看