zoukankan      html  css  js  c++  java
  • 2015 UESTC Training for Dynamic Programming A- 男神的礼物(区间dp)

    A - 男神的礼物

    Time Limit: 3000/3000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others)
     

    Lweb学长是集训队里公认的男神。有一天他要给美美的学姐姐准备礼物。

    Lweb学长可是会魔法的哟。为了准备一份礼物,男神要加工n份材料。每一次只能加工相邻的材料。

    当男神加工两个魔法值为a,b的材料,男神都要消耗a*b的体力,同时在这个地方合成出魔法值(a+b)%100的材料。

    男神为了能节省体力来完成他的礼物。想找聪明的你帮他算一算他所要花费的最小体力。

    Input

    第一行一个整数T,表示男神所要准备的礼物数。 之后的T组数据各有两行数据,第一行有一个整数n,表示这份礼物的材料数(1<=n<=100)。 接下来一行有n个整数a(0<=a<100),表示这件礼物第i份材料的魔法值。

    Output

    每组数据一行输出,表示男神制作这份礼物所要的最小体力。

    Sample input and output

    Sample InputSample Output
    2
    2
    18 19
    3
    40 60 20
    342
    2400

    Hint

    对于样例 2:

    先加工材料40和60,得到0的材料,消耗4060体力,共消耗2400体力;

    再加工材料0和20,得到20的材料,消耗020体力,共消耗2400体力.

    解题思路:

      裸裸的区间dp,虽然是模板题,但是还是啃了好久才做出来。

      dp[i][j]表示的是把第i堆的材料合并到第j堆所需要的最小代价是多少。

      状态转移方程:dp[i][j] = min(dp[i][j],dp[i][k],dp[k+1][j]+ (sum[k]-sum[l-1])%100+(sum[j]-sum[k])%100);

      初始条件:dp[i][j] = inf;

      经过菠萝爷的一番讲解,明白了很多的区间dp问题都是从dp[i][j]中划分出来一个k,接下来我们要做的就是枚举k,看那个k能够把dp[i][j]分成dp[i][k]和dp[k+1][j]的形式

      使得最终的花费达到最小.

    代码:

     1 # include<cstdio>
     2 # include<iostream>
     3 # include<cstring>
     4 
     5 using namespace std;
     6 
     7 # define MAX 123
     8 # define inf 99999999
     9 
    10 
    11 int a[MAX];
    12 int dp[MAX][MAX];
    13 int sum[MAX];
    14 
    15 int cal ( int i,int j )
    16 {
    17     if ( dp[i][j] >=0 )
    18         return dp[i][j];
    19     else if ( i==j-1 )
    20         dp[i][j] = a[i]*a[j];
    21     else if ( i==j )
    22         return 0;
    23     else
    24     {
    25         dp[i][j] = inf;
    26         for ( int k = i;k <= j;k++ )
    27         {
    28             int  temp = cal(i,k)+cal(k+1,j)+((sum[k]-sum[i-1])%100)*((sum[j]-sum[k])%100);
    29             if ( temp < dp[i][j] )
    30             {
    31                 dp[i][j] = temp;
    32             }
    33         }
    34     }
    35      return dp[i][j];
    36 }
    37 
    38 int main(void)
    39 {
    40     int t;scanf("%d",&t);
    41     while ( t-- )
    42     {
    43         int n;scanf("%d",&n);
    44         for ( int i = 1;i <= n;i++ )
    45         {
    46             scanf("%d",&a[i]);
    47             sum[i] = sum[i-1]+a[i];
    48         }
    49         memset(dp,-1,sizeof(dp));
    50         int ans = cal(1,n);
    51 
    52         printf("%d
    ",ans);
    53     }
    54 
    55 
    56     return 0;
    57 }

      

  • 相关阅读:
    ASP.NET Core 中文文档 第四章 MVC(3.2)Razor 语法参考
    ASP.NET Core 中文文档 第四章 MVC(3.1)视图概述
    ASP.NET Core 中文文档 第四章 MVC(2.3)格式化响应数据
    ASP.NET Core 中文文档 第四章 MVC(2.2)模型验证
    ASP.NET Core 中文文档 第四章 MVC(2.1)模型绑定
    ASP.NET Core 中文文档 第四章 MVC(01)ASP.NET Core MVC 概览
    mysql 解除正在死锁的状态
    基于原生JS的jsonp方法的实现
    HTML 如何显示英文单、双引号
    win2008 r2 服务器php+mysql+sqlserver2008运行环境配置(从安装、优化、安全等)
  • 原文地址:https://www.cnblogs.com/wikioibai/p/4503685.html
Copyright © 2011-2022 走看看