POJ1390 Blocks 【动态规划】
Time Limit: 5000MS | Memory Limit: 65536K | |
Total Submissions: 4173 | Accepted: 1661 |
Description
The corresponding picture will be as shown below:

Figure 1
If some adjacent boxes are all of the same color, and both the box to its left(if it exists) and its right(if it exists) are of some other color, we call it a 'box segment'. There are 4 box segments. That is: gold, silver, bronze, gold. There are 1, 4, 3, 1
box(es) in the segments respectively.
Every time, you can click a box, then the whole segment containing that box DISAPPEARS. If that segment is composed of k boxes, you will get k*k points. for example, if you click on a silver box, the silver segment disappears, you got 4*4=16 points.
Now let's look at the picture below:
Figure 2
The first one is OPTIMAL.
Find the highest score you can get, given an initial state of this game.
Input
1~n.
Output
Sample Input
2
9
1 2 2 2 2 3 3 3 1
1
1
Sample Output
Case 1: 29
Case 2: 1
题意:给定n个方块,当中有些颜色是连续的,每次点击一个方块就能够消除掉跟它连续的同样的颜色的方块,获得积分为消除长度的平方。给定一个方块序列,求最大能获得多少积分。
题解:状态方程score[i][j][k]为将连续小块统计成大块后从第i个到第j个慷慨块且第j个后面有k个连续的与其同色的方块所获得的最大积分。
我认为有问题的代码。仿照着讲义代码写的。可是也能AC。并且时间消耗是344ms。 应该是那个地方我没理解:
#include <stdio.h>
#include <string.h>
#define maxn 200 struct Node{
int color, len;
} segment[maxn];
int score[maxn][maxn][maxn], arr[maxn]; int clickBox(int left, int right, int exLen)
{
if(score[left][right][exLen]) return score[left][right][exLen];
int i, ans, ans2;
ans = segment[right].len + exLen;
ans = ans * ans;
if(left == right) return score[left][right][exLen] = ans;
ans += clickBox(left, right - 1, 0);
for(i = right - 1; i >= left; --i){
if(segment[i].color != segment[right].color) continue;
ans2 = clickBox(left, i, exLen + segment[right].len) +
clickBox(i + 1, right - 1, 0);
if(ans2 <= ans) continue;
ans = ans2; break;
}
return score[left][right][exLen] = ans;
} int main()
{
int t, n, i, id, cas = 1;
scanf("%d", &t);
while(t--){
scanf("%d", &n);
for(i = 0; i < n; ++i) scanf("%d", arr + i);
memset(score, 0, sizeof(score));
segment[id = 0].color = arr[0];
segment[id].len = 1;
for(i = 1; i < n; ++i){
if(arr[i] != arr[i-1]){
segment[++id].color = arr[i];
segment[id].len = 1;
}else ++segment[id].len;
}
printf("Case %d: %d\n", cas++, clickBox(0, id, 0));
}
return 0;
}
我认为没问题的代码,时间消耗1688ms:
#include <stdio.h>
#include <string.h>
#define maxn 200 struct Node{
int color, len;
} segment[maxn];
int score[maxn][maxn][maxn], arr[maxn]; int clickBox(int left, int right, int exLen)
{
if(score[left][right][exLen]) return score[left][right][exLen];
int i, ans, ans2;
ans = segment[right].len + exLen;
ans = ans * ans;
if(left == right) return score[left][right][exLen] = ans;
ans += clickBox(left, right - 1, 0);
for(i = right - 1; i >= left; --i){
if(segment[i].color != segment[right].color) continue;
ans2 = clickBox(left, i, exLen + segment[right].len) +
clickBox(i + 1, right - 1, 0);
if(ans2 > ans) ans = ans2;
}
return score[left][right][exLen] = ans;
} int main()
{
int t, n, i, id, cas = 1;
scanf("%d", &t);
while(t--){
scanf("%d", &n);
for(i = 0; i < n; ++i) scanf("%d", arr + i);
memset(score, 0, sizeof(score));
segment[id = 0].color = arr[0];
segment[id].len = 1;
for(i = 1; i < n; ++i){
if(arr[i] != arr[i-1]){
segment[++id].color = arr[i];
segment[id].len = 1;
}else ++segment[id].len;
}
printf("Case %d: %d\n", cas++, clickBox(0, id, 0));
}
return 0;
}
POJ1390 Blocks 【动态规划】的更多相关文章
- POJ1390 Blocks (区间DP)
题目链接:POJ 1390.Blocks 题意: 有n个方块排成一列,每个方块有颜色即1到n的一个值,每次操作可以把一段相同颜色的方块拿走,长度为k,则获得的分数为 \(k\times k\),求可获 ...
- UVA10559&POJ1390 Blocks 区间DP
题目传送门:http://poj.org/problem?id=1390 题意:给出一个长为$N$的串,可以每次消除颜色相同的一段并获得其长度平方的分数,求最大分数.数据组数$\leq 15$,$N ...
- [poj1390]Blocks(方块消除)
题目大意:给定一序列,可点击某一位置消除与其相邻且相同的方块,得分为$len*len$,求最大得分. 解题关键:关键是状态的构造,首先离散化一下,令$dp[i][j][k]$表示序列$i-j$且后面有 ...
- 常规DP专题练习
POJ2279 Mr. Young's Picture Permutations 题意 Language:Default Mr. Young's Picture Permutations Time L ...
- POJ-1390-Blocks (复杂区间DP)
$ POJ~1390~~Blocks: $ (很难想的区间DP) $ solution: $ 很好的一道题目.看起来似乎很简单,当时一直认为可以用二维区间DP来完成,转移 $ n^3 $ . 后来发现 ...
- 【POJ-1390】Blocks 区间DP
Blocks Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 5252 Accepted: 2165 Descriptio ...
- 【poj1390】 Blocks
http://poj.org/problem?id=1390 (题目链接) 题意 给出一排方块,每次可以把颜色相同的消掉,获得长度的平方的分数,问最大得分. Solution 蜜汁dp.. 我们把颜色 ...
- poj 1390 Blocks
poj 1390 Blocks 题意 一排带有颜色的砖块,每一个可以消除相同颜色的砖块,,每一次可以到块数k的平方分数.问怎么消能使分数最大.. 题解 此题在徐源盛<对一类动态规划问题的研究&g ...
- poj 动态规划题目列表及总结
此文转载别人,希望自己能够做完这些题目! 1.POJ动态规划题目列表 容易:1018, 1050, 1083, 1088, 1125, 1143, 1157, 1163, 1178, 1179, 11 ...
随机推荐
- [SPOJ 30669] Ada and Trip
[题目链接] https://www.spoj.com/problems/ADATRIP/ [算法] 直接使用dijkstra堆优化算法即可 [代码] #include<bits/stdc++. ...
- 树状数组 poj2352 Stars
2019-05-20 22:52:07 加油,坚持,加油,坚持 !!! #include<iostream> #include<cstdio> #include<cstr ...
- 28. Implement strStr()[E]实现strStr()
题目 Implement strStr(). Return the index of the first occurrence of needle in haystack, or -1 if need ...
- Lucene中Analyzer语句分析
Lucene中Analyzer语句分析,利用lucene中自带的词法分析工具Analyzer,进行对句子的分析. 源代码如下: package com.test; import java.io.IOE ...
- JavaScript之BOM和DOM
前戏 到目前为止,我们已经学过了JavaScript的一些简单的语法.但是这些简单的语法,并没有和浏览器有任何交互. 也就是我们还不能制作一些我们经常看到的网页的一些交互,我们需要继续学习BOM和DO ...
- centos6.6--------反向DNS配置
一.反向区: 将域名解析为IP====================================================================================注 ...
- Sybase 动态改变存储过程里查询的数据库
declare @sql varchar(500) select @sql='select * from '+@dbName+'..tableName' --此句用于执行拼接好的SQL语句 exec( ...
- 读《Android电视机(机顶盒)初次开发的一些经验分享》后的笔记
原文: http://blog.csdn.net/tanghongchang123/article/details/52982818 一.基本命令: 1.adb connect [ip] 2. adb ...
- sphinx with discuz
安装sphinx: sudo apt-get install sphinxsearch 配置: source discuz { type = mysql sql_host = xx.xx.xx.xx ...
- UWP 利用DataGrid控件创建表格
通过 Nuget 搜索 Microsoft.Toolkit.Uwp.UI.Controls.DataGrid 安装库,在XAML文件中添加引用库 xmlns:controls="using: ...