1. 程式人生 > >bzoj1584 9.20考試 cleaning up 打掃衛生

bzoj1584 9.20考試 cleaning up 打掃衛生

des problems lib farmer 原理 code pac n+1 崩潰

1584: [Usaco2009 Mar]Cleaning Up 打掃衛生

Time Limit: 10 Sec Memory Limit: 64 MB
Submit: 549 Solved: 382
[Submit][Status][Discuss]

Description

有N頭奶牛,每頭那牛都有一個標號Pi,1 <= Pi <= M <= N <= 40000。現在Farmer John要把這些奶牛分成若幹段,定義每段的不河蟹度為:若這段裏有k個不同的數,那不河蟹度為k*k。那總的不河蟹度就是所有段的不河蟹度的總和。

Input

第一行:兩個整數N,M

第2..N+1行:N個整數代表每個奶牛的編號

Output

一個整數,代表最小不河蟹度

Sample Input

13 4
1
2
1
3
2
2
3
4
3
4
3
1
4

Sample Output

11

HINT

   這道題當時是被m坑了所以先提前聲明一下m沒有任何卵用,沒有任何卵用,沒有任何卵用!又被絲薄出題人坑了。

   當時以為m是限制的次數,然後就開始手推了十多分鐘的樣例,各種搞都沒用,然後就快崩潰了,TMm到底是什麽呀?於是萬念俱灰的我打了一個大爆搜,然後驚喜的發現m真的不是次數,然後就等著這個暴力拿分了,連正解都沒去再想,天知道O(n^2)能拿70分,直接跪了,疼啊。

  正解個人表示根本看不懂,於是乎向指針恒學了一下暴力。

  同n^2的暴力一樣,原理也是一樣,暴力枚舉,但我們可以觀察到對於一個點,他的最優解一定小於等於i所以我們只要枚舉到不同的點有sqrt(i)就可以直接退出了,省了不少時間,其次也是最重要的一點,別用min,用if比較。

技術分享
 1 #pragma GCC optimze("O3")
 2 #include<iostream>
 3 #include<cstdlib>
 4 #include<cstdio>
 5 #include<cstring>
 6 #include<queue>
 7 #include<algorithm>
 8
#include<cmath> 9 #include<map> 10 #include<vector> 11 #define N 40005 12 using namespace std; 13 int n,m,a[N],f[N],pre[N]; 14 bool fw[N]; 15 int main() 16 { 17 scanf("%d%d",&n,&m); 18 for(int i=1;i<=n;i++) 19 scanf("%d",&a[i]); 20 memset(f,0xf,sizeof(f)); 21 f[0]=0; 22 memset(pre,-1,sizeof(pre)); 23 for(int i=1;i<=n;i++) 24 { 25 f[i]=i; 26 int js=0; 27 memset(fw,0,sizeof(fw)); 28 for(int j=i;j>=0;j--) 29 { 30 if(!fw[a[j]])js++,fw[a[j]]=1; 31 if(js*js>=i)break; 32 if(f[i]>f[j-1]+js*js) 33 f[i]=f[j-1]+js*js; 34 } 35 pre[a[i]]=i; 36 } 37 printf("%d\n",f[n]); 38 return 0; 39 }
View Code

bzoj1584 9.20考試 cleaning up 打掃衛生