zoukankan      html  css  js  c++  java
  • hdu4455 dp

    http://acm.hdu.edu.cn/showproblem.php?pid=4455

    Substrings

    Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 2229    Accepted Submission(s): 695


    Problem Description
    XXX has an array of length n. XXX wants to know that, for a given w, what is the sum of the distinct elements’ number in all substrings of length w. For example, the array is { 1 1 2 3 4 4 5 } When w = 3, there are five substrings of length 3. They are (1,1,2),(1,2,3),(2,3,4),(3,4,4),(4,4,5)
    The distinct elements’ number of those five substrings are 2,3,3,2,2.
    So the sum of the distinct elements’ number should be 2+3+3+2+2 = 12
     

    Input
    There are several test cases.
    Each test case starts with a positive integer n, the array length. The next line consists of n integers a1,a2…an, representing the elements of the array.
    Then there is a line with an integer Q, the number of queries. At last Q lines follow, each contains one integer w, the substring length of query. The input data ends with n = 0 For all cases, 0<w<=n<=106, 0<=Q<=104, 0<= a1,a2…an <=106
     

    Output
    For each test case, your program should output exactly Q lines, the sum of the distinct number in all substrings of length w for each query.
     

    Sample Input
    7 1 1 2 3 4 4 5 3 1 2 3 0
     

    Sample Output
    7 10 12
    /**
    hdu4455  dp
    题目大意:给定一个序列,求其全部长度为w的子区间中不同元素的个数之和
    解题思路:这个题与其说是dp还不如说是递推好一些。首先定义c[i]表示前面近期的与其同样的数的距离是i的数的个数,sum[i]表示前面近期的与其同样的数
              的距离大于等于i的数的个数。num[i]表示最后一个长度为i的区间含有的不同数的个数。dp[1]=n,dp[i]=dp[i-1]-num[i]+sum[i];
    */
    #include <stdio.h>
    #include <algorithm>
    #include <string.h>
    #include <iostream>
    using namespace std;
    const int maxn=1000050;
    typedef long long LL;
    int c[maxn],sum[maxn],num[maxn],pre[maxn];
    LL dp[maxn];
    int n,m,a[maxn];
    int main()
    {
        while(~scanf("%d",&n))
        {
            if(n==0)break;
            for(int i=1;i<=n;i++)
            {
                scanf("%d",&a[i]);
            }
            memset(pre,0,sizeof(pre));
            memset(c,0,sizeof(c));
            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>0;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]]==0)
                {
                    num[i]=num[i-1]+1;
                    c[a[n-i+1]]=1;
                }
                else
                {
                    num[i]=num[i-1];
                }
            }
            dp[1]=n;
            for(int i=2;i<=n;i++)
            {
                dp[i]=dp[i-1]-num[i-1]+sum[i];
            }
            scanf("%d",&m);
            for(int i=0;i<m;i++)
            {
                int x;
                scanf("%d",&x);
                printf("%I64d
    ",dp[x]);
            }
        }
        return 0;
    }
    


  • 相关阅读:
    SCCM 补丁更新 失误排错一例
    Oracle 远程连接 DB配置 连接命令
    反向代理服务器
    用JMF播放音频 例子
    HTML css兼容
    Java国际化
    JBPM 之介绍,使用
    Nginx内核优化引用
    Nginx 学习
    局域网访问VMware虚拟机中的Ubuntu
  • 原文地址:https://www.cnblogs.com/yangykaifa/p/7221309.html
Copyright © 2011-2022 走看看