• 【bzoj1584/Usaco2009 Mar】Cleaning Up 打扫卫生——动态规划+递推


    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

    很妙的一个dp啊,果然不会写....

    用到一个(显而易见的)结论:不存在一段中有超过sqrt(n)种不同的数字->因为求最小值啊。

    hzwer的题解:戳这里

    复杂度:O(n*sqrt(n))

    代码:

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<queue>
     4 #include<cmath>
     5 #include<algorithm>
     6 #define mem(a,p) memset(a,p,sizeof(a))
     7 const int N=4e4+10;
     8 using std::min;
     9 int f[N],n,m,a[N],la[N],cnt[N],b[N];
    10 int read(){
    11     int ans=0,f=1;char c=getchar();
    12     while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    13     while(c>='0'&&c<='9'){ans=ans*10+c-48;c=getchar();}
    14     return ans*f;
    15 }
    16 int main(){
    17     n=read();m=read();f[0]=0;
    18     for(int i=1;i<=n;i++)a[i]=read(),f[i]=i;
    19     int sqr=sqrt(n);
    20     for(int i=1;i<=n;i++){
    21         for(int j=1;j<=sqr;j++)
    22             if(la[a[i]]<=b[j])cnt[j]++;
    23         la[a[i]]=i;
    24         for(int j=1;j<=sqr;j++){
    25             if(cnt[j]>j){
    26                 int t=b[j]+1;
    27                 while(la[a[t]]>t)t++;
    28                 b[j]=t;cnt[j]--;
    29             }
    30             f[i]=min(f[i],f[b[j]]+j*j);
    31         }
    32     }
    33     printf("%d
    ",f[n]);
    34     return 0;
    35 }
    bzoj1584
  • 相关阅读:
    为jquery添加扩展标准思路
    linux 相关命令
    通过设置PHPSESSID保存到cookie实现免登录
    CentOs7 配置nfs 系统
    ajax 异步 跨域上传图片
    php下载并安装pear脚本
    php基于swoole扩展的WebSocket
    php冒泡排序
    微信公众号验证TOKEN
    CSS清浮动处理(Clear与BFC)
  • 原文地址:https://www.cnblogs.com/JKAI/p/7663347.html
Copyright © 2020-2023  润新知