bzoj 1584: [Usaco2009 Mar]Cleaning Up 打扫卫生【dp】
参考:http://hzwer.com/3917.html
好神啊
注意到如果分成n段,那么答案为n,所以每一段最大值为\( \sqrt{n} \)
先把相邻并且值相等的弃掉
设f[i]为到i的最小答案,b[j]表示的是从b[j]+1开始到i共有j个不同的数字,p[a[i]]表示a[i]上次出现的位置,c[j]表示b[j]+1到i的不同数字个数
转移是f[i]=min(f[b[j]]+j*j)
b[i]的更改是每次i++时,先更新c,即如果p[a[i]]<=b[j]则c[j]++;
如果c[j]++了,那么就要从b[i]+1开始找一个只在b[j]+1到i出现一次的,删到它为止
时间复杂度为\( O(n\sqrt{n}) \)
#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
const int N=40005,S=205;
int n,m,a[N],f[N],b[S],c[S],p[N],tot;
int read()
{
int r=0,f=1;
char p=getchar();
while(p>'9'||p<'0')
{
if(p=='-')
f=-1;
p=getchar();
}
while(p>='0'&&p<='9')
{
r=r*10+p-48;
p=getchar();
}
return r*f;
}
int main()
{
n=read(),m=read();
for(int i=0;i<=n;i++)
f[i]=1e9,p[i]=-1;
for(int i=1;i<=n;i++)
{
int x=read();
if(x!=a[tot])
a[++tot]=x;
}
n=tot,m=sqrt(n);
f[0]=0;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
if(p[a[i]]<=b[j])
c[j]++;
p[a[i]]=i;
for(int j=1;j<=m;j++)
if(c[j]>j)
{
int now=b[j]+1;
while(p[a[now]]>now)
now++;
b[j]=now,c[j]--;
}
for(int j=1;j<=m;j++)
f[i]=min(f[i],f[b[j]]+j*j);
}
printf("%d\n",f[n]);
return 0;
}
bzoj 1584: [Usaco2009 Mar]Cleaning Up 打扫卫生【dp】的更多相关文章
- DP经典 BZOJ 1584: [Usaco2009 Mar]Cleaning Up 打扫卫生
BZOJ 1584: [Usaco2009 Mar]Cleaning Up 打扫卫生 Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 419 Solve ...
- bzoj:1584: [Usaco2009 Mar]Cleaning Up 打扫卫生
Description 有N头奶牛,每头那牛都有一个标号Pi,1 <= Pi <= M <= N <= 40000.现在Farmer John要把这些奶牛分成若干段,定义每段的 ...
- 【BZOJ】1584: [Usaco2009 Mar]Cleaning Up 打扫卫生
[算法]DP+数学优化 [题意]把n个1~m的数字分成k段,每段的价值为段内不同数字个数的平方,求最小总价值.n,m,ai<=40000 [题解] 参考自:WerKeyTom_FTD 令f[i] ...
- BZOJ_1584_[Usaco2009 Mar]Cleaning Up 打扫卫生_DP
BZOJ_1584_[Usaco2009 Mar]Cleaning Up 打扫卫生_DP Description 有N头奶牛,每头那牛都有一个标号Pi,1 <= Pi <= M <= ...
- BZOJ1584 [Usaco2009 Mar]Cleaning Up 打扫卫生
令$f[i]$表示以i为结尾的答案最小值,则$f[i] = min \{f[j] + cnt[j + 1][i]^2\}_{1 \leq j < i}$,其中$cnt[j + 1][i]$表示$ ...
- [bzoj1587] [Usaco2009 Mar]Cleaning Up 打扫卫生
首先(看题解)可得...分成的任意一段中的不同颜色个数都<=根号n...不然的话直接分成n段会更优= = 然后就好做多了.. 先预处理出对于每头牛i,和它颜色相同的前一头和后一头牛的位置. 假设 ...
- 【动态规划】bzoj1584: [Usaco2009 Mar]Cleaning Up 打扫卫生
思路自然的巧妙dp Description 有N头奶牛,每头那牛都有一个标号Pi,1 <= Pi <= M <= N <= 40000.现在Farmer John要把这些奶牛分 ...
- [BZOJ1584] [Usaco2009 Mar]Cleaning Up 打扫卫生(DP)
传送门 不会啊,看了好久的题解才看懂 TT 因为可以直接分成n段,所以就得到一个答案n,求解最小的答案,肯定是 <= n 的, 所以每一段中的不同数的个数都必须 <= sqrt(n),不然 ...
- bzoj1584 [Usaco2009 Mar]Cleaning Up 打扫卫生 动态规划+思维
Description 有N头奶牛,每头那牛都有一个标号Pi,1 <= Pi <= M <= N <= 40000.现在Farmer John要把这些奶牛分成若干段,定义每段的 ...
随机推荐
- 多光源 MultipleLight
使用2个Pass增加光照效果: 第一个Pass是基础光源,一般是第一个平行光:Tags{"LightMode" = "ForwardBase"} 第二个光源是增 ...
- Python接口测试之报告(十五)
在本文章中,主要使用jenkins和编写的自动化测试代码,来生成漂亮的测试报告,关于什么是CI这些 我就不详细的介绍了,这里我们主要是实战为主. 首先搭建java的环境,这个这里不做介绍.搭建好jav ...
- 测试自动化接口jenkins配置
<br/><font color="red" size"3" face="微软雅黑">本邮件是程序自动下发,请勿回复 ...
- mysql ab主从复制出错及解决过程
一.mysql主从服务器报错描述:Slave_IO_Running=NO,Slave_SQL_Running=YES,Last_Errno=0 mysql slave stop ; mysql sla ...
- 592. Fraction Addition and Subtraction
Problem statement: Given a string representing an expression of fraction addition and subtraction, y ...
- codeforces 369B
#include<stdio.h>//题没读懂,没做出来 int main() { int n,k,l,r,s,s1,m,a,i; while(scanf("%d%d% ...
- python之练习-三层菜单
今天练习编写显示3层城市名称并可以返回上一层以及退出程序. Readme: 程序概述1:程序名称为:menu_three.py2:记录省,市,县的原始文件名为:areafile3:areafile文件 ...
- [bzoj2527][Poi2011]Meteors_整体二分_树状数组
Meteors bzoj-2527 Poi-2011 题目大意:题目链接. 注释:略. 想法: 首先答案可以离线,且具有单调性. 这里的单调性就是随着时间的推移,每个国家收集的陨石数增加. 不难想到整 ...
- Strongly connected-HDU4635
Problem - 4635 http://acm.hdu.edu.cn/showproblem.php?pid=4635 题目大意: n个点,m条边,求最多再加几条边,然后这个图不是强连通 分析: ...
- js的声明与引入
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...