[CSP-S模拟测试]:集合合并(记忆化搜索)
题目传送门(内部题133)
输入格式
第一行一个正整数$n$。
第二行$n$个正整数$a_i$,表示一开始有$S_i=\{a_i\}$
输出格式
输出一个非负整数表示最大的收益之和
样例
样例输入:
4
1 2 2 2
样例输出:
5
数据范围与提示
样例解释:
先合并第一个和第二个,得到$\{1,2\},\{2\},\{2\}$,产生的收益为$1$
再合并第一个和第二个,得到$\{1,2\},\{2\}$,产生的收益为$2$
再合并这两个,得到$\{1,2\}$,产生的收益为$2$
所以答案是$5$
数据范围:
对于$30\%$的数据,有$1\leqslant n\leqslant 7$
对于$50\%$的数据,有$1\leqslant n\leqslant 50$
对于$100\%$的数据,有$1\leqslant n\leqslant 300,1\leqslant a_i\leqslant n$
题解
感觉记忆化搜索比区间$DP$好打一些。
设$dp[l][r]$表示合并完$[l,r]$的最大收益,$con[l][r]$表示$[l,r]$区间内元素的个数($\Theta(n^3)$预处理即可,当然也可以用$bitset$做到$\Theta(\frac{n^3}{\omega})$,或者主席树做到$\Theta(n^2\log n)$)。
转移也很简单:
$$dp[l][r]=\max\limits_{i=l}^{r-1}dp[l][i]+dp[i+1][r]+con[l][i]\times con[i+1][r]$$
处理环的话无非就是断环为链即可。
时间复杂度:$\Theta(n^3)$。
期望得分:$100$分。
实际得分:$100$分。
代码时刻
#include<bits/stdc++.h>
using namespace std;
int n;
int a[601],con[601][601];
long long dp[601][601],ans;
bitset<300> v[601][601];
long long dfs(int l,int r)
{
if(l==r)dp[l][r]=0;
if(dp[l][r]!=-1)return dp[l][r];
for(int i=l;i<r;i++)
dp[l][r]=max(dp[l][r],dfs(l,i)+dfs(i+1,r)+1LL*con[l][i]*con[i+1][r]);
return dp[l][r];
}
int main()
{
memset(dp,-1,sizeof(dp));
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
a[i+n]=a[i];
}
for(int i=1;i<=2*n;i++)
{
v[i][i][a[i]]=con[i][i]=1;
for(int j=i+1;j<=2*n;j++)
{
v[i][j]=v[i][j-1];
v[i][j][a[j]]=1;
con[i][j]=v[i][j].count();
}
}
for(int i=1;i<=n;i++)ans=max(ans,dfs(i,i+n-1));
printf("%lld\n",ans);
return 0;
}
rp++
[CSP-S模拟测试]:集合合并(记忆化搜索)的更多相关文章
- HDU 3779 Railroad(记忆化搜索)
Railroad Time Limit : 4000/2000ms (Java/Other) Memory Limit : 32768/32768K (Java/Other) Total Subm ...
- [CSP-S模拟测试]:彩球问题(记忆化搜索)
题目传送门(内部题91) 输入格式 第一行一个正整数$N$,表示颜色种类数. 第二行$N$个正整数$k[i],k[i]$表示第$i$种颜色的数量$(1\leqslant k[i]\leqslant 3 ...
- 【10.31校内测试】【组合数学】【记忆化搜索/DP】【多起点多终点二进制拆位Spfa】
Solution 注意取模!!! Code #include<bits/stdc++.h> #define mod 1000000007 #define LL long long usin ...
- 【BZOJ-3895】取石子 记忆化搜索 + 博弈
3895: 取石子 Time Limit: 1 Sec Memory Limit: 512 MBSubmit: 263 Solved: 127[Submit][Status][Discuss] D ...
- HDU-1428(记忆化搜索)
Problem Description LL 最近沉迷于AC不能自拔,每天寝室.机房两点一线.由于长时间坐在电脑边,缺乏运动.他决定充分利用每次从寝室到机房的时间,在校园里散散步.整个HDU 校园呈方 ...
- 2017广东工业大学程序设计竞赛决赛 题解&源码(A,数学解方程,B,贪心博弈,C,递归,D,水,E,贪心,面试题,F,贪心,枚举,LCA,G,dp,记忆化搜索,H,思维题)
心得: 这比赛真的是不要不要的,pending了一下午,也不知道对错,直接做过去就是了,也没有管太多! Problem A: 两只老虎 Description 来,我们先来放松下,听听儿歌,一起“唱” ...
- 记忆化搜索 codevs 2241 排序二叉树
codevs 2241 排序二叉树 ★ 输入文件:bstree.in 输出文件:bstree.out 简单对比时间限制:1 s 内存限制:128 MB [问题描述] 一个边长为n的正三 ...
- 最大联通子数组之和(dfs,记忆化搜索,状态压缩)
最大联通子数组,这次的题目,我采用的方法为dfs搜索,按照已经取到的数v[][],来进行搜索过程的状态转移,每次对v[][]中标记为1的所有元素依次取其相邻的未被标记为1的元素,将其标记为1,然而,这 ...
- HDU 4597 Play Game(记忆化搜索,深搜)
题目 //传说中的记忆化搜索,好吧,就是用深搜//多做题吧,,这个解法是搜来的,蛮好理解的 //题目大意:给出两堆牌,只能从最上和最下取,然后两个人轮流取,都按照自己最优的策略,//问说第一个人对多的 ...
随机推荐
- 单个html5页面加个密码访问
单个html5页面要实现加个密码才能访问,可以用js来控制.代码加在<head>插入下面代码</head>代码如下: <script languange="Ja ...
- JAVA break、continue和return的区别
控制跳转:continue和break的区别,以为return Continue在循环中使用,一般在for中使用 Break:跳出单重循环,常和switch搭配使用. 效果区别 Break的结果如下: ...
- python词云生成-wordcloud库
python词云生成-wordcloud库 全文转载于'https://www.cnblogs.com/nickchen121/p/11208274.html#autoid-0-0-0' 一.word ...
- ubuntu16.04 Installing PHP 7.2
//install sudo add-apt-repository ppa:ondrej/php sudo apt-get update sudo apt-get install php7.2 //C ...
- 用js方式取得接口里面json数据的key和value值
大家在实际操作中难免遇到对接口的问题,想必对一些小白来说取得里面想要是数据也是很是头疼,那么接下来我会结合接口实际情况教大家怎么取得里面相应的数据 接口数据例如:(数据为 模拟数据,json格式) { ...
- python的加密方式
MD5加密 这是一种使用非常广泛的加密方式,不可逆的,在日常字符串加密中经常会用到,下面我简单介绍一下这种方式,主要用到Python自带的模块hashlib,测试代码如下,先创建一个md5对象,然后直 ...
- 使用maven构建dubbo服务的可执行jar包+Dubbo 程序实例
https://blog.csdn.net/zsg88/article/details/76100482 https://blog.csdn.net/zsg88/article/details/762 ...
- Proxy.newInstance与InvocationHandler的使用示例
先定义一个接口,根据代理模式的原理,被代理类与代理类都要实现它. public interface Person { void eat(); } 再写一个实际执行任务的类(被代理类): public ...
- golang连接activemq,发送接收数据
介绍 使用golang连接activemq发送数据的话,需要使用一个叫做stomp的包,直接go get github.com/go-stomp/stomp即可 代码 生产者 package main ...
- NFS 网络文件系统快速部署手册
NFS服务端部署配置 一.安装nfs-utils和rpcbind服务,安装完后检查 # yum install -y nfs-utils rpcbind # rpm -qa nfs-utils rpc ...