zoukankan      html  css  js  c++  java
  • zoj-3872 Beauty of Array (dp)

    ]Edward has an array A with N integers. He defines the beauty of an array as the summation of all distinct integers in the array. Now Edward wants to know the summation of the beauty of all contiguous subarray of the array A.

    Input

    There are multiple test cases. The first line of input contains an integer Tindicating the number of test cases. For each test case:

    The first line contains an integer N (1 <= N <= 100000), which indicates the size of the array. The next line contains N positive integers separated by spaces. Every integer is no larger than 1000000.

    <h4< dd="">Output

    For each case, print the answer in one line.

    <h4< dd="">Sample Input

    3
    5
    1 2 3 4 5
    3
    2 3 3
    4
    2 3 3 2
    

    <h4< dd="">Sample Outpu1021

    38


    这题题意的理解有一定难度,本人借鉴了一位大神的博客,得知大致的题意如下:
    这个题的意思就是给n个数,求这n个数的子序列中不算重复的数的和。
    比如第二个样例他的子序列就是{2},{2,3},{2,3,3},{3},{3,3},{3};
    但每个子序列中重复的元素不被算入,所以他们的总和就是2+5+5+3+3+3=21;
    但是这题的数据是1e5,用暴力肯定会超时,又因为每个子序列之间都有一定的递推关系,每个序列可以分解为无数个子序列。
    依此,可以推断该题用dp写。
    dp转移方程怎么推?用一个例子比较好解释,还用上面的例子给定4个数,分别是2 3 3 2,存入nu[Max]数组中,用dp[Max]记录子序列和(即前缀和)。
    从第一个数往后推每一种可能性,则是:
                              2
                     3       3 2
              3     3 3     3 3 2
        2    2 3    2 3 3    2 3 3 2
       dp[1]  dp[2]   dp[3]     dp[4]

    由上可知,dp[i]=dp[i-1]+nu[i]*i;
    但该题要求去掉子序列中的重复元素,该怎么去呢?
    我们继续利用上例的数据进行去重处理,可得:
                            2
                   3       3 2
            3      3     3 2
      2    2 3    2 3     3 2
     dp[1]  dp[2]   dp[3]     dp[4]

    如上,每一个序列中都没有重复的元素了
    由上两图对比可知,可以想到用一个book[Max*10]数组记录每一个元素最后出现的位置,把nu[i]*i改成nu[i]*(i-book[nu[i]])
    即转移方程改为:dp[i]=dp[i-1]+nu[i]*(i-book[nu[i]]);然后把dp[n]中的值相加即可;

    这题还有个坑点,对dp[n]求和会爆int,应用long long;

    代码如下:
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <iostream>
    using namespace std;
    const int M = 111111;
    long long book[M*10],dp[M],nu[M];
    int main(){
    	int t;
    	cin>>t;
    	while(t--){
    		long long ans=0;
    		memset(book,0,sizeof(book));
    		memset(dp,0,sizeof(dp));
    		int n;
    		cin>>n;
    		for(int i=1;i<=n;i++){
    			cin>>nu[i];
    			
    		}
    		for(int i=1;i<=n;i++){
    			dp[i]=dp[i-1]+nu[i]*(i-book[nu[i]]);
    			book[nu[i]]=i;
    			ans+=dp[i];	
    		}
    		cout<<ans<<endl;
    	}
    	return 0;
    }
    

    参考博客:http://blog.csdn.net/zhao5502169/article/details/70037098  





  • 相关阅读:
    (黑马十次方项目day06)@ConfigurationProperties报错的解决方式
    (黑马十次方项目day04)An attempt was made to call a method that does not exist. The attempt was made from the following location:
    (黑马十次方项目day02)使用map接收form表单的参数
    (黑马十次方项目day02)IDEA在方法之间添加分隔符及开启Run Dashboard管理
    (黑马十次方项目day01)spring-boot-starter-parent 包maven依赖报错
    (黑马十次方项目day01)从PDF文件中复制代码到pom文件中project报错
    ER图学习
    java 8 函数式库Vavr功能
    Guava Cache
    UML学习
  • 原文地址:https://www.cnblogs.com/zmin/p/7281981.html
Copyright © 2011-2022 走看看