UVA 10559 Blocks(区间DP&&递推)
题目大意:给你玩一个一维版的消灭星星,得分是当前消去的区间的长度的平方,求最大得分。
现在分析一下题目
因为得分是长度的平方,不能直接累加,所以在计算得分时需要考虑前一个状态所消去的长度,仅用dp[l][r]来表示区间最大得分是不足以用来转移的。
我们的解决方法是:增加一维预测未来可能会出现的情况,用dp[l][r][t]表示区间[l,r]之后附加t个与r同色的方块时所能得到的最大值。为了降低时间复杂度,我们可以在读入时处理一下,将一段长度为a、颜色为b的区间k表示成一个len[k]=a,col[k]=b的“点”。这样,当我们计算dp[l][r][0]时,首先尝试直接消除区间r,得到dp[l][r][0]=dp[l][r-1][0]+(len[r])^2,接着,将它之后所有可能的附加t个同色方块的情况都算出来:dp[l][r][t]=dp[l][r-1][0]+(len[r]+t)^2。之后,在[l,r-1]之间寻找可能与区间r同色的区间k,若col[r]==col[k],则尝试消除区间r与k之间的所有方块,让区间r与k并在一起计算分数并更新所有dp[l][r][t]的值:dp[l][r][t]=max(dp[l][r][t],dp[l][k][len[r]+t]+dp[k+1][r-1][0])。最后dp[1][n][0]即为答案。(n为一开始同色区间的数量)
代码:(140ms,用递推速度就是不一样,比记搜不知道高到哪里去了)
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int col[],len[],dp[][][];
int sum[];
//by sclbgw7
inline int sq(int x)
{return x*x;} inline int maxn(int x,int y)
{return x>y?x:y;} int main()
{
int T,time;
scanf("%d",&T);
for(time=;time<=T;++time)
{
int n=,m,t1;//m为方块个数,n为区间个数
scanf("%d",&m);
for(int i=;i<=m;++i)
{
scanf("%d",&t1);
if(t1==col[n])
++len[n];
else
{
col[++n]=t1;
len[n]=;
}
}
for(int i=;i<=n;++i)
sum[i]=sum[i-]+len[i];//sum为前缀和,用于限定预测t的范围
memset(dp,,sizeof(dp));
for(int i=;i<n;++i)
for(int l=;l+i<=n;++l)
{
int r=l+i,re=sum[n]-sum[r];//re为当前t可能用到的最大值
for(int t=;t<=re;++t)
dp[l][r][t]=dp[l][r-][]+sq(t+len[r]);
for(int k=r-;k>=l;--k)
if(col[k]==col[r])
for(int t=;t<=re;++t)
dp[l][r][t]=maxn(dp[l][r][t],dp[l][k][len[r]+t]+dp[k+][r-][]);
}
printf("Case %d: %d\n",time,dp[][n][]);
//神坑!!!!!冒号之后要加一个空格!!!!!!!
}
return ;
}
UVA 10559 Blocks(区间DP&&递推)的更多相关文章
- UVA 10559 Blocks——区间dp
题目:https://www.luogu.org/problemnew/show/UVA10559 应该想到区间dp.但怎么设计状态? 因为连续的东西有分值,所以应该记录一下连续的有多少个. 只要记录 ...
- UVA 10559 Blocks —— 区间DP
题目:https://www.luogu.org/problemnew/show/UVA10559 区间DP,有点难想: 为了方便,先把原来就是连续一段相同颜色的点看做一个点,记一下长度: f[i][ ...
- 紫书 例题 9-9 UVa 10003 (区间dp+递推顺序)
区间dp,可以以一个区间为状态,f[i][j]是第i个切点到第j个切点的木棍的最小费用 那么对于当前这一个区间,枚举切点k, 可以得出f[i][j] = min{dp(i, k) + dp(k, j) ...
- hdu2089(数位DP 递推形式)
不要62 Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submis ...
- uva 10328 - Coin Toss 投硬币(dp递推,大数)
题意:抛出n次硬币(有顺序),求至少k个以上的连续正面的情况的种数. 思路:转换成求抛n个硬币,至多k-1个连续的情况种数,用所有可能出现的情况种数减去至多k-1个的情况,就得到答案了.此题涉及大数加 ...
- UVA 10559 Blocks
题目大意:有一串带颜色的方块,每次可以消掉颜色相同的一段,得到size^2的分数,问最多能得到多少分数.n≤200. 给这题状态跪下来. 显然的区间DP,但设f[i][j]是不够的. 考虑到之前做过的 ...
- UVA 11077 - Find the Permutations(递推)
UVA 11077 - Find the Permutations option=com_onlinejudge&Itemid=8&page=show_problem&cate ...
- 【POJ-1390】Blocks 区间DP
Blocks Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 5252 Accepted: 2165 Descriptio ...
- hdu 2604 Queuing(dp递推)
昨晚搞的第二道矩阵快速幂,一开始我还想直接套个矩阵上去(原谅哥模板题做多了),后来看清楚题意后觉得有点像之前做的数位dp的水题,于是就用数位dp的方法去分析,推了好一会总算推出它的递推关系式了(还是菜 ...
随机推荐
- java基础-Integer类常用方法介绍
java基础-Integer类常用方法介绍 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 在实际程序使用中,程序界面上用户输入的数据都是以字符串类型进行存储的.而程序开发中,我们需 ...
- jsp中jsp:forward 与 redirect区别
部分转载:http://hi.baidu.com/168zlf/item/2f4b2ad4351b881c20e2500c 在网上看到一些帖子,总结了一些区别,可以从以下几个方面来看: 1.从地址栏显 ...
- radioButton drawable selector
1.实现radioButton drawable selector更改图片,在drawable文件夹下,新建selector文件, <selector xmlns:android="h ...
- Spring容器事件、自定义事件
Spring容器内置事件,如容器的启动.停止.关闭.销毁等事件 <bean name="contextStartedHandler" class="com.nuts ...
- 关于数据区间变换及numpy数组转图片数据的python实现
python实现区间转换.numpy图片数据转换 需求: 客户的需求是永无止境的,这不?前几天,用户提出了一个需求,需要将一组数据从一个区间缩放到另一区间? 思路: 先将数据归一化,再乘以对应区间的差 ...
- Android笔记之开机自启
有时候需要应用具有开机自启的能力,或者更常见的场景是开机时悄悄在后台启动一个Service. 关键点: 1. Android系统在开机的时候会发送一条广播消息,只需要接收这条广播消息即可,不过需要注意 ...
- D. Makoto and a Blackboard(积性函数+DP)
题目链接:http://codeforces.com/contest/1097/problem/D 题目大意:给你n和k,每一次可以选取n的因子代替n,然后问你k次操作之后,每个因子的期望. 具体思路 ...
- 【bzoj题解】1012 最大数
题目描述 现在请求你维护一个数列,要求提供以下两种操作:1.查询操作.语法:Q L 功能:查询当前数列中末尾L个数中的最大的数,并输出这个数的值.限制:L不超过当前数列的长度.2.插入操作.语法:A ...
- mysql 在windons下的备份命令
1. @echo off set "Ymd=%date:~,4%%date:~5,2%%date:~8,2%" mysqldump -uroot -proot jy510 > ...
- ispoweroftwo 判断2的次幂
首先结果是: public bool IsPowerOfTwo(int n) { if(n<1) return false;//2的次幂一定大于0 return ((n & (n -1) ...