• cf779D(记忆化dp)


    题目链接: http://codeforces.com/problemset/problem/799/D

    题意: 给出两个矩阵边长 a, b, 和 w, h, 以及一个 c 数组, 可选择 c 数组中任意数字乘上w 或 h. 数组中每个数字最多只能用一次. 求最少选择多少个数字可使得边长为 a, b 的矩阵能放到变化后的矩阵中.

    思路: log2(1e5) = 17, 即最多需要对一条边乘17个数字, 要是完全暴力的话需要 2^34 的时间复杂度, 显然不行.

    本题 dp 可解, 先给 c 降序排列, 用 dp[i][j] = k 表示到第 i 个元素, 其中一条边为 j 时另外一条边最大为 k.

    那么动态转移方程式为: dp[i][j] = max(dp[i - 1][j / c[i]], dp[i - 1][j] * c[i])

    但是用普通 dp 的话会有两个问题, 其一是 j / c[i] 整除问题, 这个可以先判断一下能否整除解决. 其二是 w * c[i] 非常大, 如:

    100000 100000 99999 99999 2
    30000 30000

    设定  0 < j <= 1e5 显然不够, 要是 j 太大则会 tle. 虽然不一定没有解决的方法, 但是显然可以不用这么麻烦, 将其改成记忆化dp即可.

    代码:

     1 #include <iostream>
     2 #include <stdio.h>
     3 #include <string.h>
     4 #include <algorithm>
     5 #define ll long long
     6 using namespace std;
     7 
     8 const int MAXN = 4e5 + 10;
     9 ll c[MAXN], dp[40][MAXN];
    10 int n, a, b;
    11 
    12 bool cmp(ll x, ll y){
    13     return x > y;
    14 }
    15 
    16 int dfs(int indx, ll w, ll h){
    17     if(w >= a && h >= b || w >= b && h >= a) return indx;
    18     if(indx > 34 || indx >= n) return MAXN;
    19     if(w >= 1e5) w = 1e5; //注意越界
    20     if(h >= 1e5) h = 1e5;
    21     if(dp[indx][w] != -1) return dp[indx][w];
    22     return dp[indx][w] = min(dfs(indx + 1, w * c[indx], h), dfs(indx + 1, w, h * c[indx]));
    23 }
    24 
    25 int main(void){
    26     int h, w;
    27     scanf("%d%d%d%d%d", &a, &b, &h, &w, &n);
    28     for(int i = 0; i < n; i++){
    29         scanf("%lld", &c[i]);
    30     }
    31     sort(c, c + n, cmp);
    32     memset(dp, -1, sizeof(dp));
    33     int sol = dfs(0, w, h);
    34     if(sol != MAXN) cout << sol << endl;
    35     else cout << -1 << endl;
    36     return 0;
    37 }
    View Code
  • 相关阅读:
    java中的>>>作用及使用
    配置服务器SSH PAM防止暴力破解
    uniapp 中实现 onLaunch 异步回调后执行 onLoad 最佳实践
    Traefic 入门
    C# foreach
    consul .netcore
    扩容Azure免费虚拟机的硬盘大小
    编译boost库的dll和lib
    SecureCRT查看LINUX日志单条报文过长无法显示解决方法
    MySQL查询各个分组中的前几条数据/每个分类的前几条数据
  • 原文地址:https://www.cnblogs.com/geloutingyu/p/7134334.html
Copyright © 2020-2023  润新知