zoukankan      html  css  js  c++  java
  • 【动态规划】Mathematical Curse

    【来源】:2018年焦作网络赛B

    【题意】:

      有n个数字,有m个符号运算。通过不回头(即选取m个数有顺序可言),消除巫术的,并达到最大的价值。

      其实意思就是在数组里选取一段子序列,然后进行m次加减乘除的运算。最后使答案最大化。

    【思路】:

      考虑DP,我们考虑加减时只需要考虑最大值即可,但是乘除两个运算的加入就会使这个题目变得复杂了。

      然后我们需要的记录最大值和最小值,因为每一个值可能是从最大值转移过来,也有可能最小值转移过来的。

      所以需要同时记录。

    【注意】:

      1、记得初始化(多组数据)

      2、如果直接转移会耗费O(n^2),其实我们只是关心前i个里面获取的最大值,所以我们需要压缩,从前一个数字的暂存值进行更新。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll;
     4 const int N = 1e4+10;
     5 const int M = 6;
     6 const ll inf = 0x7fffffffffffffff;
     7 ll dp[N][M][2]; //0_ 最小值 ,1 最大值
     8 ll a[N];
     9 int main(){
    10     int T;
    11     int n,m,k;
    12     char opt[M] ;
    13     for( scanf("%d",&T) ; T ;T-- ){
    14         scanf("%d%d%d",&n,&m,&k);
    15         for(int i=1;i<=n;i++)   scanf("%lld",&a[i]);
    16         scanf("%s",opt+1);
    17 
    18         for(int i=0;i<=n;i++){
    19             for(int j=0;j<=m;j++){
    20                 dp[i][j][0] =  inf ;
    21                 dp[i][j][1] = -inf ;
    22             }
    23         }
    24 
    25         for(int i=0;i<=n;i++){
    26             dp[i][0][0] = dp[i][0][1] = k;
    27         }
    28 
    29 
    30         for(int j=1;j<=m;j++){
    31             for(int i=1;i<=n;i++){
    32                 if( i > j ){
    33                     dp[i][j][0] = dp[i-1][j][0];
    34                     dp[i][j][1] = dp[i-1][j][1];
    35                 }
    36 
    37                 if( opt[j] =='+'){
    38                     dp[i][j][0] = min( dp[i][j][0] , dp[i-1][j-1][0] + a[i] );
    39                     dp[i][j][0] = min( dp[i][j][0] , dp[i-1][j-1][1] + a[i] );
    40 
    41                     dp[i][j][1] = max( dp[i][j][1] , dp[i-1][j-1][0] + a[i] );
    42                     dp[i][j][1] = max( dp[i][j][1] , dp[i-1][j-1][1] + a[i] );
    43                 }else if( opt[j] == '-'){
    44                     dp[i][j][0] = min( dp[i][j][0] , dp[i-1][j-1][0] - a[i] );
    45                     dp[i][j][0] = min( dp[i][j][0] , dp[i-1][j-1][1] - a[i] );
    46 
    47                     dp[i][j][1] = max( dp[i][j][1] , dp[i-1][j-1][0] - a[i] );
    48                     dp[i][j][1] = max( dp[i][j][1] , dp[i-1][j-1][1] - a[i] );
    49                 }else if( opt[j] == '*' ){
    50                     dp[i][j][0] = min( dp[i][j][0] , dp[i-1][j-1][0] * a[i] );
    51                     dp[i][j][0] = min( dp[i][j][0] , dp[i-1][j-1][1] * a[i] );
    52 
    53                     dp[i][j][1] = max( dp[i][j][1] , dp[i-1][j-1][0] * a[i] );
    54                     dp[i][j][1] = max( dp[i][j][1] , dp[i-1][j-1][1] * a[i] );
    55                 }else{
    56                     dp[i][j][0] = min( dp[i][j][0] , dp[i-1][j-1][0] / a[i] );
    57                     dp[i][j][0] = min( dp[i][j][0] , dp[i-1][j-1][1] / a[i] );
    58 
    59                     dp[i][j][1] = max( dp[i][j][1] , dp[i-1][j-1][0] / a[i] );
    60                     dp[i][j][1] = max( dp[i][j][1] , dp[i-1][j-1][1] / a[i] );
    61                 }
    62             }
    63         }
    64 
    65         printf("%lld
    ",dp[n][m][1]);
    66     }
    67     return 0 ;
    68 }
    View Code
  • 相关阅读:
    支持向量机 (三): 优化方法与支持向量回归
    支持向量机 (二): 软间隔 svm 与 核函数
    支持向量机 (一): 线性可分类 svm
    拉格朗日乘子法
    特征选择: 卡方检验、F 检验和互信息
    Python 多进程、多线程效率比较
    Umi+Dva搭建Cesium 3D开发环境
    React 项目生产版本迭代页面不刷新问题
    React-Native学习手册----搭建基于ios平台的开发环境
    Cesium 绘制点、线、面和测距
  • 原文地址:https://www.cnblogs.com/Osea/p/11297908.html
Copyright © 2011-2022 走看看