zoukankan      html  css  js  c++  java
  • BZOJ1584: [Usaco2009 Mar]Cleaning Up 打扫卫生

    Description

    有 N头奶牛,每头那牛都有一个标号Pi,1 <= Pi <= M <= N <= 40000。现在Farmer John要把这些奶牛分成若干段,定义每段的不河蟹度为:若这段里有k个不同的数,那不河蟹度为k*k。那总的不河蟹度就是所有段的不河蟹度的总和。

    题目:http://www.lydsy.com/JudgeOnline/problem.php?id=1584

    题解:

    比较神的DP。。。最近怎么老遇神题。。。

     一些注释写在代码里

     1 #include<cstdio>
     2 
     3 #include<cstdlib>
     4 
     5 #include<cmath>
     6 
     7 #include<cstring>
     8 
     9 #include<algorithm>
    10 
    11 #include<iostream>
    12 
    13 #include<vector>
    14 
    15 #include<map>
    16 
    17 #include<set>
    18 
    19 #include<queue>
    20 
    21 #include<string>
    22 
    23 #define inf 1000000000
    24 
    25 #define maxn 50000
    26 
    27 #define maxm 500+100
    28 
    29 #define eps 1e-10
    30 
    31 #define ll long long
    32 
    33 #define pa pair<int,int>
    34 
    35 #define for0(i,n) for(int i=0;i<=(n);i++)
    36 
    37 #define for1(i,n) for(int i=1;i<=(n);i++)
    38 
    39 #define for2(i,x,y) for(int i=(x);i<=(y);i++)
    40 
    41 #define for3(i,x,y) for(int i=(x);i>=(y);i--)
    42 
    43 #define mod 1000000007
    44 
    45 using namespace std;
    46 
    47 inline int read()
    48 
    49 {
    50 
    51     int x=0,f=1;char ch=getchar();
    52 
    53     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    54 
    55     while(ch>='0'&&ch<='9'){x=10*x+ch-'0';ch=getchar();}
    56 
    57     return x*f;
    58 
    59 }
    60 int n,m,a[maxn],b[maxn],c[maxn],f[maxn],pre[maxn];
    61 
    62 int main()
    63 
    64 {
    65 
    66     freopen("input.txt","r",stdin);
    67 
    68     freopen("output.txt","w",stdout);
    69 
    70     n=read();m=read();m=sqrt(n);
    71     for1(i,n)a[i]=read();
    72     memset(f,60,sizeof(f));
    73     memset(pre,-1,sizeof(pre));//pre[i]表示i在序列中上一次出现的位置
    74     f[0]=0;
    75     for1(i,n)
    76     {
    77         for1(j,m)if(pre[a[i]]<=b[j])c[j]++;//b[j]表示b[j]+1到i有<=j个不同的数字
    78         pre[a[i]]=i;
    79         for1(j,m)
    80         if(c[j]>j)//c[j]表示b[j]+1到i出现的不同数字的个数,如果>j显然不合b[j]的定义,所以要删数
    81          {
    82              int t=b[j]+1;//指针
    83              while(pre[a[t]]>t)t++;//往前扫,pre[a[t]]>t表示在t到i之间还有a[t],所以继续前移,知道出现某个数的后继还没有出现,意为在i之后
    84              b[j]=t;c[j]--;
    85          }
    86         for1(j,m)f[i]=min(f[i],f[b[j]]+j*j);
    87     }
    88     printf("%d
    ",f[n]);
    89 
    90     return 0;
    91 
    92 }
    View Code

     

     

     

  • 相关阅读:
    108. Convert Sorted Array to Binary Search Tree
    107. Binary Tree Level Order Traversal II
    106. Construct Binary Tree from Inorder and Postorder Traversal
    105. Construct Binary Tree from Preorder and Inorder Traversal
    104. Maximum Depth of Binary Tree
    103. Binary Tree Zigzag Level Order Traversal
    102. Binary Tree Level Order Traversal
    系统和进程相关信息
    文件I/0缓冲
    系统编程概念(文件系统mount等函数的使用)
  • 原文地址:https://www.cnblogs.com/zyfzyf/p/4060025.html
Copyright © 2011-2022 走看看