• hdu4283 You Are the One 区间DP


    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4283

    自己想了很久还是不会,参考了别人的思路才写的,区间DP还是很弱,继续努力!!

    思路:

    转载:

    题解:想dp[i][j]表示[i ,j]内的unhappiness最小值,枚举k(i<=k<j),有两种情况需要讨论:
              1 如果[i , k]区间内的人全部在[k+1, j]区间内的人之前出列,且已经全部不在栈中,即[i , j]区间可以分为[i , k] , [k+1 ,j]两个完全相同的子问题,
                 即dp[i][j] =MIN(dp[i][j] , dp[i][k] + dp[k+1][j] + (sum[j] – sum[i]) * (k – i +1));
              2 如果[i , k]区间内的人全部在[k+1 , j]区间内的人之后出列,即[i , k]区间内的人全部需要进栈,所以出来的顺序是逆序的,需O(n2)预处理出against_order[i][j]
                 表示[i , j]区间人逆序出来的unhappiness值,即dp[i][j] = MIN(dp[i][j] , dp[k+1][j] + against_order[i][k] + (sum[k]– sum[i-1]) * (j - k));

    我用了记忆化搜索和迭代两种方式实现,主要是为了加深自己的理解和记忆

    记忆化搜索代码 :

     1 #include<iostream>
     2 #include<cstdlib>
     3 #include<cstdio>
     4 #include<cstring>
     5 using namespace  std;
     6 #define  INF 1000010111
     7 int n;
     8 int a[110];
     9 int dp[110][110];
    10 int sum[110];
    11 int order[110][110];
    12 void Make_order()
    13 {
    14         memset(order,0,sizeof(order));
    15         for(int j=1;j<=n;j++)
    16                 for(int i=j-1;i>=1;i--)
    17                         order[i][j]=order[i+1][j]+a[i]*(j-i);
    18 
    19 }
    20 int dfs(int i,int j)
    21 {
    22         if(dp[i][j]<INF) return dp[i][j];
    23         if(i==j) return dp[i][j]=0;
    24         for(int k=i;k<j;k++)
    25                 dp[i][j]=min(dp[i][j],min(dfs(i,k)+dfs(k+1,j)+(sum[j]-sum[k])*(k-i+1),dp[k+1][j]+order[i][k]+(sum[k]-sum[i-1])*(j-k)));
    26                 return dp[i][j];
    27 }
    28 int main()
    29 {
    30         int t;
    31         scanf("%d",&t);
    32         int tol=1;
    33         while(t--)
    34         {
    35                 sum[0]=0;
    36                 scanf("%d",&n);
    37                 for(int i=1;i<=n;i++)
    38                    {
    39                            scanf("%d",&a[i]);
    40                            sum[i]=sum[i-1]+a[i];
    41                    }
    42                 Make_order();
    43                   for(int i=0;i<110;i++)
    44                       for(int j=0;j<110;j++)
    45                               dp[i][j]=INF;
    46                   cout<<"Case #"<<tol++<<": "<<dfs(1,n)<<endl;
    47         }
    48 
    49 
    50 }

    迭代代码:

     1 #include<iostream>
     2 #include<cstdlib>
     3 #include<cstdio>
     4 #include<cstring>
     5 using namespace std;
     6 #define INF 100001000
     7 int dp[110][110];
     8 int a[110];
     9 int sum[110];
    10 int order[110][110];
    11 int n;
    12 void init()
    13 {
    14         scanf("%d",&n);
    15        sum[0]=0;
    16        for(int i=1;i<=n;i++)
    17        {
    18                scanf("%d",&a[i]);
    19                sum[i]=sum[i-1]+a[i];
    20        }
    21        for(int i=1;i<110;i++)
    22            for(int j=i;j<110;j++)
    23                    if(i==j) dp[i][j]=0;
    24                    else dp[i][j]=INF;
    25        memset(order,0,sizeof(order));
    26        for(int j=1;j<=n;j++)
    27           for(int i=j-1;i>=1;i--)
    28                   order[i][j]=order[i+1][j]+a[i]*(j-i);
    29 }
    30 
    31 int main()
    32 {
    33         int t;
    34         int tol=1;
    35         scanf("%d",&t);
    36         while(t--)
    37         {
    38           init();
    39           for(int j=1;j<=n;j++)
    40              for(int i=j-1;i>=1;i--)
    41                {
    42                   for(int k=i;k<j;k++)
    43                     dp[i][j]=min(dp[i][j],min(dp[i][k]+dp[k+1][j]+(sum[j]-sum[k])*(k-i+1),dp[k+1][j]+order[i][k]+(sum[k]-sum[i-1])*(j-k)));
    44                }
    45                cout<<"Case #"<<tol++<<": "<<dp[1][n]<<endl;
    46         }
    47         return 0;
    48      
    49 }
  • 相关阅读:
    Redis学习篇(一)之String类型及其操作
    MySQL笔记(五)之表的连接
    MySQL笔记(三)之数据插入更新与删除
    MySQL笔记(四)之内建函数
    MySQL笔记(二)之数据检索常用关键字
    MySQL笔记(一)之新建数据库和数据表
    京东文胸数据分析
    用SpringSecurity从零搭建pc项目-02
    Spring Security构建Rest服务-0800-Spring Security图片验证码
    用SpringSecurity从零搭建pc项目-01
  • 原文地址:https://www.cnblogs.com/xiaozhuyang/p/hdu4283.html
Copyright © 2020-2023  润新知