zoukankan      html  css  js  c++  java
  • HDU 5115 (杀狼,区间DP)

    题意:你是一个战士现在面对,一群狼,每只狼都有一定的主动攻击力和附带攻击力。你杀死一只狼。你会受到这只狼的(主动攻击力+旁边两只狼的附带攻击力)这么多伤害~现在问你如何选择杀狼的顺序使的杀完所有狼时,   自己受到的伤害最小。(提醒,狼杀死后就消失,身边原本相隔的两只狼会变成相邻,而且不需要考虑狼围城环这种情况)

    题解:明显的区间DP,但是这题中需要自己确定一个 方案,不难想到先打2边在打中间; 

       子问题:在区间i,j上的代价; 

       划分:区间的直接合并的过程中,是区间和区间合并还是区间和点合并,即分割点是不是在边界;

     总结:又是初始化,在dp问题的初始化上已经错了许多次了,写出转移方程后,一定要注意好边界情况以及 f 的第一项

     1 #include <cstdio>
     2 #include <iostream>
     3 #include <cstring>
     4 using namespace std;
     5 
     6 const int maxn=205;
     7 const int INF=0x3f3f3f3f;
     8 int f[maxn][maxn], a[maxn], b[maxn];
     9 
    10 int main()
    11 {
    12     //freopen("in.txt", "r", stdin);
    13     int T, kase=0; cin>>T;
    14     while(T--)
    15     {
    16         memset(a, 0, sizeof(a));
    17         memset(b, 0, sizeof(b));
    18         memset(f, 0, sizeof(f));
    19         //memset(f, 0x3f, sizeof(f));
    20         //这题的状态转移方程,有个f[i][k-1]和f[k+1][j]
    21         int n; cin>>n;
    22         for(int i=1; i<=n; i++)
    23             cin>>a[i];
    24         for(int i=1; i<=n; i++)
    25             cin>>b[i];
    26 
    27         memset(f, 0x3f, sizeof(f));
    28         for(int i=1; i<=n; i++)
    29             f[i][i]=a[i]+b[i-1]+b[i+1];  //f的边界,这里不写也行,把len从0开始就可以了;
    30 
    31         for(int len=1; len<n; len++)
    32             for(int i=1; i<=n-len; i++)
    33             {
    34                 int j=i+len;
    35                 for(int k=i; k<=j; k++) //k的范围要注意,是可以等于i和j的
    36                 {
    37                     if(k!=j&&k!=i)
    38                         f[i][j]=min(f[i][j], f[i][k-1]+a[k]+f[k+1][j]+b[i-1]+b[j+1]);
    39                     else if(k==j)
    40                         f[i][j]=min(f[i][j], f[i][k-1]+a[k]+b[i-1]+b[j+1]);
    41                     else
    42                         f[i][j]=min(f[i][j], a[k]+f[k+1][j]+b[i-1]+b[j+1]);
    43                     //以下的写法也可以AC,就是不判断k是否在端点, 不过这样写的话初始化就要好好注意一下了
    44                     //f[i][j]=min(f[i][j], f[i][k-1]+a[k]+f[k+1][j]+b[i-1]+b[j+1]);
    45                 }
    46             }
    47         printf("Case #%d: %d
    ", ++kase, f[1][n]);
    48     }
    49     return 0;
    50 }
  • 相关阅读:
    Java面向对象
    Java方法
    Java控制语句
    Java接收用户键盘输入
    Java运算符
    Java类型转换
    Java的加载与执行
    Java关键字
    Java常见的DOS命令及JDK
    nginx学习要点记录
  • 原文地址:https://www.cnblogs.com/Yokel062/p/10765281.html
Copyright © 2011-2022 走看看