• HDU5653 Bomber Man wants to bomb an Array 简单DP


    题意:bc 77 div1 1003(中文题面)

    分析:先不考虑将结果乘以 1e6。 设 dp[i] 为从前 i 个格子的状态可以获得的最大破坏指数。

    那么我们可以枚举每个炸弹,该炸弹向左延伸的距离和向又延伸的距离。

    设第 i 个炸弹破坏区间为 [l, r], 则 dp[r] = dp[l - 1] + log2(r - l + 1)。答案就是 dp[n - 1]。不要忘记最后要向下取整。

    注:我对官方题解稍作解释,dp[i]代表前i个格子可以获得的最大破坏指数

    但是更新的时候,需要注意,假设有 n 个炸弹,第 i 个炸弹的位置是o[i]

    那么考虑处理到第i个炸弹,他能更新的dp[j]是有限制的,o[i]<=j<o[i+1],因为一个炸弹的爆炸区域不可能跨过另外一个炸弹

    更新dp[j]的也dp[k]也是有限制的,o[i-1]<=k<=o[i],道理是一样的

    然后看起来是三重循环,实际上很小

    然后有一个小优化,事先把log2(1-2000)打出来,因为这个函数很慢

    #include<cstdio>
    #include<cstring>
    #include<queue>
    #include<cstdlib>
    #include<algorithm>
    #include<vector>
    #include<cmath>
    using namespace std;
    typedef long long LL;
    const int N=2e3+5;
    const int INF=0x3f3f3f3f;
    int o[N];
    double dp[N],val[N];
    int main(){
        for(int i=1;i<=2001;++i)
          val[i]=log(i)/log(2);
        int T;
        scanf("%d",&T);
        while(T--){
          int n,m;
          scanf("%d%d",&n,&m);
          for(int i=1;i<=m;++i)
           scanf("%d",&o[i]),++o[i];
          sort(o+1,o+1+m); 
          memset(dp,0,sizeof(dp));
          int c=m>1?o[2]:n+1;
          for(int i=o[1];i<c;++i)
            dp[i]=val[i];
          for(int i=2;i<=m;++i)
            for(int j=i<m?o[i+1]-1:n;j>=o[i];--j)
              for(int k=o[i-1];k<o[i];++k)
                dp[j]=max(dp[j],dp[k]+val[j-k]);
           printf("%d
    ",(int)(floor(dp[n]*1e6)));
         }
        return 0;
    }
    View Code
  • 相关阅读:
    一、dynamic
    一、提问方式
    金额大写
    1、过滤敏感字符
    一、简单的移动端tab头部二级下拉导航栏,向下弹出,向上隐藏
    一、简单的图片上传并预览功能input[file]
    【2019-11-16】做人和做企业是一个同心圆
    【2019-11-15】销售门槛低,但前途无量
    【2019-11-14】乐观扩宽了自己想象的范围
    【2019-11-13】看到别人的是孤独,其实是独处
  • 原文地址:https://www.cnblogs.com/shuguangzw/p/5324511.html
Copyright © 2020-2023  润新知