• STDU 1309:不老的传说问题 区间DP好题


    不老的传说问题

    题目链接:

    http://acm.sdut.edu.cn/sdutoj/problem.php?action=showproblem&problemid=1309

    题意:

    中文题,和杭电2476挺像的

    题解:

    比较简单,关于k的限制只要在DP的时候加上特判就好了,设dp[i][j]为区间[i,j]内的最少次数,设k点是[i,j-1]中的某一点,则在一般情况下dp[i][j]=min(dp[i][j],dp[i][k-1]+dp[k][j]),这一点应该毫无疑问。那么这里主要就是要特判特殊情况了,也就是当s[k]==s[j]且k到j的距离不超过限制的时候,可以知道dp[i][k-1]不会影响到dp[k][j]的部分,由于s[k]与s[j]相同,因此在刷点 k 的时候可以同时把点 j 也刷了,因此此时dp[i][j]=min(dp[i][j],dp[i][k-1]+dp[k][j])

    再考虑第二个条件,涂刷石头是顺时针的,也就是说序列是成环的,那么只需要再创建一个s并接到原来的序列后边,使长度变成原来的双倍,这时候只要求出所有的dp[i][i+n-1]的最小值就好了,比较简单的一道题。

                  

    代码

    #include<stdio.h>
    const int N=201;
    int s[N*2],dp[N*2][N*2];
    int mmin(int x,int y)
    {
      return x<y?x:y;
    }
    void Get_Dp(int n,int mx)
    {
      for(int len=0;len<n;++len)
      {
        for(int i=1;i+len<=n;++i)
        {
          int j=i+len;
          dp[i][j]=dp[i][j-1]+1;
          for(int k=i;k<j;++k)
          if(s[j]==s[k]&&j-k+1<=mx)dp[i][j]=mmin(dp[i][j],dp[i][k-1]+dp[k][j-1]);
          else dp[i][j]=mmin(dp[i][j],dp[i][k-1]+dp[k][j]);
        }
      }
    }
    void solve()
    {
      int n,m,k,res;
      while(~scanf("%d%d%d",&n,&m,&k))
      {
        for(int i=1;i<=n;++i)
        scanf("%d",&s[i]),s[i+n]=s[i];
        Get_Dp(n*2,k);
        res=dp[1][n];
        for(int i=1;i<=n;++i)
        if(dp[i][i+n-1]<res)res=dp[i][i+n-1];
        printf("%d ",res);
      }
    }
    int main()
    {
      solve();
      return 0;
    }

  • 相关阅读:
    bzoj2124-等差子序列
    线程安全问题
    IDEA导入maven中导入net.sf.json报错的解决方法
    Java写到.txt文件,如何实现换行
    POI读取Excel如何判断行为空
    为什么JAVA对象需要实现序列化?
    支付宝老版本的支付文档
    连接池和数据源的区别是什么 [
    文件下载时格式设置
    postConstruct执行过程
  • 原文地址:https://www.cnblogs.com/kiuhghcsc/p/5761165.html
Copyright © 2020-2023  润新知