zoukankan      html  css  js  c++  java
  • Bzoj1939 [Croatian2010] Zuma

    Time Limit: 4 Sec  Memory Limit: 64 MB
    Submit: 43  Solved: 31

    Description

    有一行 N 个弹子,每一个都有一个颜色。每次可以让超过 K 个的连续的同颜色的一段 弹子消失,剩下的会重新紧凑在一起。你有无限的所有颜色的弹子,要求在这行弹子中插入 最少的弹子,使得弹子全部消失。

    Input

    The first line of input contains two integers N (1 ≤ N ≤ 100) and K (2 ≤ K ≤ 5) - the number of marbles in the initial sequence and the minimal number of consecutive marbles of the same color he could wish to vanish. The next line contains exactly N integers between 1 and 100 (inclusive), separated by one space. Those numbers represent colors of marbles in the sequence Mirko found.

    Output

    The output should contain only one line with a single integer number - the minimal number of marbles Mirko has to insert to achive the desired effect.

    Sample Input

    10 4
    3 3 3 3 2 3 1 1 1 3

    Sample Output

    4

    HINT

     

    Source

    动态规划 区间DP

    参考了这里的题解 http://blog.csdn.net/u014609452/article/details/63267943

    K的限制不定,当K>3的时候,似乎不能见一段消一段了(可能三段拼起来比消两段更优),好像不太容易区间DP?

    大力脑洞一下发现还是可以DP的

    $ f[i][j][k] $表示现在要消除 i ~ j 区间,在i的左边添加了k个珠子。

    共有三种决策(@游戏王v6):

      当k<K-1的时候,我们可以再加一个,也就是 $ f[i][j][k]=min(f[i][j][k],f[i][j][k+1]+1)$

      当k=K-1的时候,可以消掉i,也就是 $ f[i][j][k]=f[i+1][j][0]$

      当i和i+1位置的颜色相同的时候,我们可以把i看做合并到i+1,也就是 $ f[i][j][k] = f[i+1][j][k+1] $

    转移有些零散,写成记忆化搜索的形式会很方便。

     1 #include<iostream>
     2 #include<algorithm>
     3 #include<cstring>
     4 #include<cstdio>
     5 #include<cmath>
     6 using namespace std;
     7 const int mxn=105;
     8 int read(){
     9     int x=0,f=1;char ch=getchar();
    10     while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    11     while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();}
    12     return x*f;
    13 }
    14 int n,K;
    15 int a[mxn];
    16 int f[mxn][mxn][mxn];
    17 int solve(int l,int r,int X){
    18     if(l>r)return 0;
    19     if(f[l][r][X]!=-1)return f[l][r][X];
    20     int &res=f[l][r][X]=0x3f3f3f3f;
    21     if(X<K-1)res=min(res,solve(l,r,X+1)+1);
    22     if(X==K-1)res=solve(l+1,r,0);
    23     for(int i=l+1;i<=r;i++)
    24         if(a[i]==a[l])
    25             res=min(res,solve(l+1,i-1,0)+solve(i,r,min(K-1,X+1)));
    26     return res;
    27 }
    28 int main(){
    29     int i,j;
    30     n=read();K=read();
    31     for(i=1;i<=n;i++)a[i]=read();
    32     memset(f,-1,sizeof f);
    33     solve(1,n,0);
    34     printf("%d
    ",f[1][n][0]);
    35     return 0;
    36 }
  • 相关阅读:
    數據從一個DB寫入另外一個DB
    js 控制下拉菜單的刷新
    Ajax 加載數據庫中的圖片
    Win7 註冊表 刪除登陸帳號
    產生隨機數
    借助AjaxControlToolkit实现百度搜索时的下拉列表提示
    解决"Windows 安装程序不允许从远程桌面连接安装"
    中文转换成数字金额C#【转】
    让你的Visual Studio 2010自动添加头部注释信息【转】
    C# 图片识别(支持21种语言)【转】
  • 原文地址:https://www.cnblogs.com/SilverNebula/p/7134256.html
Copyright © 2011-2022 走看看