hdu 4455 动态规划

来源:互联网 发布:俄罗斯美国开战知乎 编辑:程序博客网 时间:2024/05/05 08:12

Substrings

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


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
71 1 2 3 4 4 531230

Sample Output
71012

Source
2012 Asia Hangzhou Regional Contest 

题目大意:

给定一个长为n(n<=10^6)的数组,数组中的数大于0小于10^6

询问q次,询问长度为w的子数组(连续的)的权值和,子数组的权值为其数组中的不同元素的个数.


题目思路:

拿样例写一下

1: {1} , {1} , {2} , {3} , {4} , {4} , {5}

2: {1,1} , {1,2} , {2,3} , {3,4} , {4,4} , {4,5} 

3: {1,1,2} , {1,2,3} , {2,3,4} , {3,4,4} , {4,4,5} 

4: {1,1,2,3} , {1,2,3,4} , {2,3,4,4} , {3,4,4,5} 

...

容易发现可以得出一个发现:

长度为w的值肯定包含长度为w-1的值减去最后一个字数组的权值和

例:

2: {1,1} , {1,2} , {2,3} , {3,4} , {4,4} , {4,5} 

3: {1,1,2} , {1,2,3} , {2,3,4} , {3,4,4} , {4,4,5

dp[3] = dp[2] - 权值[{4,5}] + ?

而'?'就表示添加上那些标蓝色的数之后要添加的值.

设某个标蓝色的数为a[i],另外一个和它相等的且和它最近的数为a[j],且i>j

如果i-j>=w的话那么添上这个标蓝的数就可以使得dp[w]+1

所以我们只要求出cnt[dis]即可,dis既某数离在它之前且相等的且和它最近的数的距离.

#include<stdio.h>#include<string.h>#define N 1000005__int64 dp[N];int a[N],mark[N],s[N],b[N];int main(){    int n,i,m,sum;    while(scanf("%d",&n),n!=0)    {       memset(mark,0,sizeof(mark));       memset(s,0,sizeof(s));       for(i=1;i<=n;i++)       {            scanf("%d",&a[i]);            if(!mark[a[i]])            {                s[i]++;                mark[a[i]]=i;            }            else            {                s[i-mark[a[i]]]++;                mark[a[i]]=i;            }       }       memset(mark,0,sizeof(mark));       m=0;       for(i=n;i>=1;i--)       {          if(!mark[a[i]])          {              m++;              b[n-i+1]=m;              mark[a[i]]=i;          }          else  b[n-i+1]=m;       }       dp[1]=n;sum=n;       for(i=2;i<=n;i++)       {           dp[i]=dp[i-1]-b[i-1];           sum-=s[i-1];           dp[i]+=sum;       }       scanf("%d",&m);       for(i=1;i<=m;i++)       {           scanf("%d",&n);           printf("%I64d\n",dp[n]);       }    }    return 0;}


0 0
原创粉丝点击