• 九度 1532:棋盘寻宝扩展(背包方案统计)


    题目描述:

    现在有一个8*8的棋盘,上面放着64个不同价值的礼物,每个小的棋盘上面放置一个礼物(礼物的价值大于0小于100),一个人初始位置在棋盘的左上角,每次他只能向下或向右移动一步,并拿走对应棋盘上的礼物,结束位置在棋盘的右下角。从棋盘的左上角移动到右下角的时候的,每次他只能向下或向右移动一步,并拿走对应棋盘上的礼物,但是拿到的所有的礼物的价值之和不大于一个限定值limit,请设计一个算法请实现,使其能够获得不超过限制值limit的最大价值的礼物。

    思路

    1. 在棋盘问题的基础上加了一个限制, 礼物数不能超过 limit

    2. 这个限制使得状态转移方程需要进行一下变形

    3. dp[i][j][k] 表示 第 (i,j) 个格子上限制最大价值为 k 时能够获得的最大价值

    dp[i][j][k] = max(dp[i][j-1][k-matrix[i][j]], dp[i-1][j][k-matrix[i][j]]) + matrix[i][j]

    4. 初始化时需要设置为 负无穷, 表示没有线路能够在不超过 limit 的情况下得到 (i,j)

    代码

    #include <iostream>
    #include <stdio.h>
    #include <memory.h>
    using namespace std;
    
    const int INF = 10005;
    int dp[10010];
    int money[110];
    
    void dodp(int n) {
        memset(dp, 0x80, sizeof(dp));
        
        dp[0] = 0;
        for(int i = 0; i < n; i ++) {
            for(int v = INF; v >= 0; v --) {
                if(v >= money[i])
                    dp[v] = max(dp[v-money[i]]+money[i], dp[v]);
            }
        }
    
        for(int i = 0; i < INF; i++) {
    
            if(dp[i] < 0) {
                cout << i << endl;    
                break;
            }
                
        }
    }
    
    int main() {
        
        int n;
        while(scanf("%d", &n) != EOF) {
            for(int i = 0; i < n; i ++)
                scanf("%d", money+i);
            dodp(n);
        }
        return 0;
    }
  • 相关阅读:
    ArcPad 10 的安装部署
    各种机械键盘轴的差别,究竟什么轴好
    default argument given of parameter 的问题
    Quartz中时间表达式的设置-----corn表达式
    图像切割之(一)概述
    SMTP协议分析
    Android学习小Demo(19)利用Loader来实时接收短信
    qml动画控制器AnimationController
    httpclient 文件上传
    Java习题10.24
  • 原文地址:https://www.cnblogs.com/xinsheng/p/3580212.html
Copyright © 2020-2023  润新知