2021-09-27每日刷题打卡

一、POJ-1390:Blocks

1.1 问题描述

Some of you may have played a game called ‘Blocks’. There are n blocks in a row, each box has a color. Here is an example: Gold, Silver, Silver, Silver, Silver, Bronze, Bronze, Bronze, Gold.
The corresponding picture will be as shown below:

img
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 kk points. for example, if you click on a silver box, the silver segment disappears, you got 44=16 points.

Now let’s look at the picture below:

img
Figure 2

The first one is OPTIMAL.

Find the highest score you can get, given an initial state of this game.

题目大意:

有一排box,各有不同的颜色。你可以通过点击某个box使得与其相邻的同色box全部消掉,然后你可以得到的分数为消去长度的平方,问怎样得到最高分?

1.2 问题解决

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int MAXN = 205;
 
int len[MAXN],dp[MAXN][MAXN][MAXN],n,color[MAXN],cnt;
 
int DP(int x,int y,int k){
    if (dp[x][y][k])
        return dp[x][y][k];
    if (x == y)
        return (len[x]+k)*(len[x]+k);
    dp[x][y][k] = DP(x,y-1,0)+(len[y]+k)*(len[y]+k);
    for (int i = x; i < y; i++){
        if (color[y] == color[i])
            dp[x][y][k] = max(dp[x][y][k],DP(x,i,len[y]+k)+DP(i+1,y-1,0));
    }
    return dp[x][y][k];
}
 
int main(){
    int T,ans;
    scanf("%d",&T);
    for (int t = 1; t <= T; t++){
        scanf("%d",&n);
        cnt = 0;
        memset(len,0,sizeof(len));
        memset(color,0,sizeof(color));
        int temp;
        for (int i = 0; i < n; i++){
            scanf("%d",&temp);
            if (color[cnt] == temp)
                len[cnt]++;
            else {
                cnt++;
                len[cnt]++;
                color[cnt] = temp;
            }
        }
        memset(dp,0,sizeof(dp));
        ans = DP(1,cnt,0);
        printf("Case %d: ",t);
        printf("%d\n",ans);
    }
    return 0;
}

二、Leetcode-61:旋转链表

2.1 问题描述

img

2.2 问题解决

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode rotateRight(ListNode head, int k) {
        ListNode cur = head;
        ListNode last = null;
        int len = 0;
        while(cur != null)
        {
            len++;
            if(cur.next == null)
                last = cur;
            cur = cur.next;
        }
        if(len == 0) return null;
        cur = head;

        int count = len;
        int a = (k%len);            //注意取余或除的时候除数不能为0
        ListNode pre = head;
        while(cur != null)
        {
            if(a == 0) return head;
            if(count == a)
            {
                pre.next = null;
                last.next = head;

                return cur; 
            }
            count--;
            pre = cur;
            cur = cur.next;
        }

        return null;
    }
}

三、生词

block n. 障碍物

sliver n. 银

bronze n. 青铜

corresponding adj. 相应的

adjacent adj. 邻近的

segment vi. 分割

四、参考文章

  1. Blocks POJ - 1390 多维dp
  2. POJ - 1390 Blocks(记忆化搜索)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值