• SCOJ 3843 ZUMA【记忆化搜索,dp】



    http://cs.scu.edu.cn/soj/problem.action?id=3843
    SCOJ 3843 ZUMA
    大意:
    有100种不同的颜色,编号为1,2,3。。100.从中取n颗珠子排成一条直线,
    已知将某颗珠子插入到某一位置,若与该珠子连续的相同颜色的珠子个数>=k,那么与这一连串相同颜色的珠子便可全部消去
    现要消去所有珠子,问至少需要多少珠子?

    分析:
    记忆化搜索、、、、、语言组织能力太差,说不太清。。。。囧o(╯□╰)o

    #include<stdio.h>
    #include<string.h>
    
    const int MAXN = 100+5;
    const int K = 5+1;
    int n,k;
    int a[MAXN];
    int dp[MAXN][MAXN][K];//dp[l][r][cnt];//表示解决l到r,且l左边已有cnt个连续的与l相同的颜色需要的最少步数
    inline int min(int a,int b)
    {
        return a<b?a:b;
    }
    int solve(int left,int right,int cnt)//计算与left左边有连续cnt个a[left]的情况下,消去到right这段需要的最少珠子数
    {
        int &cur = dp[left][right][cnt];//使得cur指向当前值
        if(cur!=-1)return cur;
        if(left==right)
        {
            cur = k-cnt-1;
            return cur;
        }
        if(left>right)
        {
            cur = 0;
            return cur;
        }
    
        if(cnt<k-1)
            cur = solve(left,right,cnt+1)+1;
        else
            if(cnt>=k-1)//前面已经有k-1及以上个与a[left]相同,直接消去
                cur = solve(left+1,right,0);
        int i;
        for(i=left+1;i<=right;i++)
        {
            if(a[i]!=a[left])continue;
            int value = solve(left+1,i-1,0)+solve(i,right,min(cnt+1,k-1));//即连接left,i
            if(value<cur)cur = value;
        }
        return cur;
    }
    int main()
    {
        while(scanf("%d%d",&n,&k)!=EOF)
        {
            memset(dp,-1,sizeof(dp));
            int i;
            for(i=0;i<n;i++)
            {
                scanf("%d",&a[i]);
            }
            printf("%d\n",solve(0,n-1,0));
        }
        return 0;
    }
    
  • 相关阅读:
    集合综合练习<三>
    集合综合练习<二>
    集合综合练习<一>
    java打分系统
    mysql存储过程
    mysql的视图、索引、触发器、存储过程
    mysql
    Java 集合底层原理剖析(List、Set、Map、Queue)
    HashMap底层实现
    Gradle
  • 原文地址:https://www.cnblogs.com/AndreMouche/p/1966504.html
Copyright © 2020-2023  润新知