小v在vivo手机的应用商店中下载了一款名为“一维消消乐”的游戏,介绍如下:
1、给出一些不同颜色的豆子,豆子的颜色用数字(0-9)表示,即不同的数字表示不同的颜色;2、通过不断地按行消除相同颜色且连续的豆子来积分,直到所有的豆子都消掉为止;3、假如每一轮可以消除相同颜色的连续 k 个豆子(k >= 1),这样一轮之后小v将得到 k*k 个积分;4、由于仅可按行消除,不可跨行或按列消除,因此谓之“一维消消乐”。
请你帮助小v计算出最终能获得的最大积分。
1、给出一些不同颜色的豆子,豆子的颜色用数字(0-9)表示,即不同的数字表示不同的颜色;2、通过不断地按行消除相同颜色且连续的豆子来积分,直到所有的豆子都消掉为止;3、假如每一轮可以消除相同颜色的连续 k 个豆子(k >= 1),这样一轮之后小v将得到 k*k 个积分;4、由于仅可按行消除,不可跨行或按列消除,因此谓之“一维消消乐”。
输入一行n个正整数,代表这一行中豆子的颜色及排列。
示例:
输入:1 4 2 2 3 3 2 4 1
输出:21
示例说明:
第一轮消除3,获得4分,序列变成1 4 2 2 2 4 1
第二轮消除2,获得9分,序列变成1 4 4 1
第三轮消除4,获得4分,序列变成1 1
第四轮消除1,获得4分,序列为空
总共得分21分
小V最终能拿到的最大积分。
1 4 2 2 3 3 2 4 1
21
import java.io.*;
/**
* Welcome to vivo !
*/
public class Main {
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String inputStr = br.readLine();
int input[] = parseInts(inputStr.split(" "));
int output = solution(input);
System.out.println(output);
}
private static int[] parseInts(String[] strArr) {
if (strArr == null || strArr.length == 0) {
return new int[0];
}
int[] intArr = new int[strArr.length];
for (int i = 0; i < intArr.length; i++) {
intArr[i] = Integer.parseInt(strArr[i]);
}
return intArr;
}
static class Node {
Node prev;
Node next;
int val;
Node(int val){
this.val = val;
}
}
private static int solution(int[] input) {
// TODO Write your code here
Node head = new Node(0);
Node node = head;
for(int i=0;i<input.length;++i){
Node p = new Node(input[i]);
p.prev = node;
node.next = p;
node = p;
}
return search(head);
}
static int search(Node head){
if(head.next == null)return 0;
int max = 0;
Node p=head.next;
while(p!=null){
Node r=p;
int c=1;
while(r.next!=null && r.next.val==r.val){ r=r.next; ++c;}
// remove
p.prev.next = r.next;
if(r.next!=null)r.next.prev=p.prev;
int val = c*c + search(head);
// restore
p.prev.next = p;
if(r.next!=null)r.next.prev=r;
max = Math.max(max,val);
p = r.next;
}
return max;
}
} class Solution {
int n;
int[][] F;
int[] prev;
public int removeBoxes(int[] boxes) {
n = boxes.length;
prev = new int[n];
F = new int[n][n];
for (int i = 0; i < n; i++) {
prev[i] = -1;
for (int j = 0; j < n; j++) {
F[i][j] = -1;
}
for (int j = i - 1; j >= 0; --j) {
if (boxes[i] == boxes[j]) {
prev[i] = j;
break;
}
}
}
return f(0, n - 1);
}
public int f(int i, int j) {
if (i > j) {
return 0;
}
if (F[i][j] != -1) {
return F[i][j];
}
if (i == j) {
return F[i][j] = 1;
}
return F[i][j] = g(i, j, prev[j], 1);
}
public int g(int i, int j, int r, int m) {
if (i > j) {
return 0;
}
if (r < i) {
return f(i, j - 1) + m * m;
}
// 如果相邻,可以消除许多中间状态
if (r + 1 == j) {
return g(i, r, prev[r], m + 1);
}
int rv = prev[r];
return Math.max(
g(i, r, rv, m + 1) + f(r + 1, j - 1),
g(i, j, rv, m)
);
}
} // 参照中大老哥思路做的
import java.io.*;
/**
* Welcome to vivo !
*/
public class Main {
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String inputStr = br.readLine();
int input[] = parseInts(inputStr.split(" "));
int output = solution(input);
System.out.println(output);
}
private static int[] parseInts(String[] strArr) {
if (strArr == null || strArr.length == 0) {
return new int[0];
}
int[] intArr = new int[strArr.length];
for (int i = 0; i < intArr.length; i++) {
intArr[i] = Integer.parseInt(strArr[i]);
}
return intArr;
}
private static int solution(int[] input) {
// TODO Write your code here
if(input == null || input.length == 0){
return 0;
}
int len = input.length;
return DFS(input, len);
}
public static int DFS(int[] arr, int len){
if(len == 1){
return 1;
}
if(len == 2){
if(arr[0] == arr[1]){
return 4;
}else{
return 2;
}
}
int max = 0;
int L = 0;
for(int i = 1; i < len; i++){
if(arr[i] != arr[L]){
int[] copy = new int[len - (i - L)];
int j = 0;
for(; j < L; j++){
copy[j] = arr[j];
}
for(int r = i; r < len; r++){
copy[j++] = arr[r];
}
max = Math.max(max, DFS(copy, copy.length) + (i - L)*(i - L));
L = i;
}
}
if(L == 0){
return len * len;
}
int[] copy = new int[L];
for(int j = 0; j < L; j++){
copy[j] = arr[j];
}
max = Math.max(max, DFS(copy, copy.length) + (len - L) * (len - L));
return max;
}
}
/*
遍历递归
*/
#include <iostream>
#include <stdlib.h>
#include <string.h>
using namespace std;
/**
* Welcome to vivo !
*/
#define MAX_NUM 100
int solution(int boxs[], int N)
{
// cout << "N = " << N << endl;
if(N <= 0) return 0;
// if(N == 1){
// return 1;
// }
// if(N == 2){
// if(boxs[0] == boxs[1]) return 4;
// else return 2;
// }
int S=0,E=0;
int max =1,temp;
for(int i = 1;i<N;i++){
// cout << "!" << endl;
if(boxs[i] == boxs[S]){
E++;
// cout << "S";
}
if(boxs[i] != boxs[S]){
// cout << "D";
int copy[N];
int j = 0;
for(int p = 0;p<S;p++,j++){
copy[j] = boxs[p];
// cout << copy[j] << " ";
}
for(int p = E+1;p<N;p++,j++){
copy[j] = boxs[p];
// cout << copy[j] << " ";
}
// cout << endl;
int Z = solution(copy,N-(E-S+1));
temp = (E-S+1)*(E-S+1) + Z;
// cout << "temp = " << (E-S+1)*(E-S+1) << "+" << Z << endl;
max = temp>max?temp:max;
// cout << "max = " << max << endl;
S = E+1;
E = E+1;
}
}
if(S == 0 && E == (N-1)){
return (E-S+1)*(E-S+1);
}
//1 2 2 1
return max;
}
int main()
{
string str("");
getline(cin, str);
int boxs[MAX_NUM];
int i = 0;
char *p;
int count = 0;
const char* strs = str.c_str();
p = strtok((char *)strs, " ");
while(p)
{
boxs[i] = atoi(p);
count++;
p = strtok(NULL, " ");
i++;
if(i >= MAX_NUM)
break;
}
int num = solution(boxs, count);
cout << num << endl;
return 0;
} import java.io.*;
/**
* Welcome to vivo !
*/
public class Main {
private static int[][][] dp;
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String inputStr = br.readLine();
int input[] = parseInts(inputStr.split(" "));
int output = solution(input);
System.out.println(output);
}
private static int[] parseInts(String[] strArr) {
if (strArr == null || strArr.length == 0) {
return new int[0];
}
int[] intArr = new int[strArr.length];
for (int i = 0; i < intArr.length; i++) {
intArr[i] = Integer.parseInt(strArr[i]);
}
return intArr;
}
private static int solution(int[] input) {
// TODO Write your code here
int length = input.length;
dp = new int[length][length][length];
return calculatePoints(input, 0, length - 1, 0);
}
public static int calculatePoints(int[] boxes, int l, int r, int k) {
if (l > r) return 0;
if (dp[l][r][k] == 0) {
dp[l][r][k] = calculatePoints(boxes, l, r - 1, 0) + (k + 1) * (k + 1);
for (int i = l; i < r; i++) {
if (boxes[i] == boxes[r])
dp[l][r][k] = Math.max(dp[l][r][k], calculatePoints(boxes, l, i, k + 1) + calculatePoints(boxes, i + 1, r - 1, 0));
}
}
return dp[l][r][k];
}
} #!/usr/bin/python
# -*- coding: utf-8 -*-
'''
Welcome to vivo !
'''
def solution(boxes):
max_rst = 0
memo = {}
def dfs(state):
nonlocal max_rst, memo
#print(state)
if not state: # 已经全取出来了,返回0
return 0
i = 0
rst = 0 # 保存在当前状态下的最高分数
while 1:
if i == len(state):
break
c = state[i]
j = i+1
while(j < len(state) and state[j]==c): # 找连续相同子串
j+=1
next_state = state[:i]+state[j:] # 下一个状态
now_score = (j-i)**2 # 当前步骤的得分
t_state = tuple(next_state) # list 转 tuple,才能hash
if t_state not in memo.keys(): # 记忆化
memo[t_state] = dfs(next_state)
rst = max(rst, now_score + memo[t_state]) #当前操作得分+剩余状态的得分 找最大值
i = j
return rst
return dfs(boxes)
if __name__ == '__main__':
x = input()
boxes = list(map(int,x.split()))
print(solution(boxes)) dfs + 对重复状态的记忆, 应该非常直观粗暴了