zoukankan      html  css  js  c++  java
  • Beans

    题目在:http://acm.hdu.edu.cn/diy/contest_showproblem.php?pid=1010&cid=11785

           仔细分析题目,豆子都在m*n的矩阵中,假设我要选取m[i][j]处的豆子,那么一定不会选取第i-1行和i+1行的豆子,为啦使得最终获得分数最高,既然选啦m[i][j],那么对于m[i][j]不相邻的同行元素也可以选。其实说来说去就是不可以选取相邻行和相邻位置的元素,于是假设我选取啦第i行,则选取第i行中一批不的相邻元素必定存在一个最大和值s[i],对于每一行的s[i],构成的s[n]数组,与刚才处理单行最大和问题一样,选取不相邻的一批s[i]使得最终和最大。现在要解决这样一个问题:存在数列{sn},要求在数列中选取一批下标互不相邻的数使得这批数的和最大。假设m[i]表示最后一步选取的是s[i]的一批数的最大和,那么显然不可以再选择s[i-1],如果倒数第二步选择的是s[i-2],那么m[i]=s[i]+m[i-2],如果倒数第2步选择的是s[i-3],那么m[i]=m[i-3]+s[i],那么倒数第二步可能选取s[i-4]?假设可以,那么显然为了使得m[i]=s[i]+m[i-4],观察可知中间还可以选取s[i-2],这时候得到的m[i]=s[i]+s[i-2]+m[i-4]比刚才假设的最大值还要大,出现矛盾。说明k<i-3的s[k]不可能是最后一步,于是得到啦递推公式:

    m[i]=s[i]+max{m[i-2],m[i-3]};

    #include<iostream>
    using namespace std;
    #define size 2001
    int b[size][size];
    int MaxBeans(int a[], int n);
    int DP(int m, int n);
    int Max(int a, int b){
    return a > b ? a : b;
    }
    int main(){
    int i, j,m,n;
    while (cin >> m >> n){
    memset(b, 0, sizeof(b));
    for (i = 1; i <= m;i++)
    for (j = 1; j <= n; j++)
    scanf("%d", &b[i][j]);
    cout << DP(m, n) << endl;
    }
    return 0;
    }
    int MaxBeans(int a[], int n){
    int s[size] = {0};
    int i;
    s[0] = 0, s[1] = a[1], s[2] =a[2];
    for (i = 3; i <= n; i++)
    s[i] = Max(s[i - 2], s[i - 3])+a[i];
    int max =0;
    for (i = 1; i <= n;i++)
    if (max<s[i])
    max = s[i];
    return max;
    }
    int DP(int m, int n){
    int i;
    int s[size];
    for (i = 1; i <= m; i++){
    s[i] = MaxBeans(b[i], n);
    }
    int max= MaxBeans(s, m);

    return max;
    }

  • 相关阅读:
    第八章 路由器交换机及其操作系统的介绍
    k-Tree DP计数
    Drop Voicing 最长升序
    高精度
    1196D2
    C
    POJ 3974 马拉车
    2020.8.1第二十六天
    2020.7.31第二十五天
    每日日报
  • 原文地址:https://www.cnblogs.com/td15980891505/p/4964809.html
Copyright © 2011-2022 走看看