zoukankan      html  css  js  c++  java
  • b_360_限制每次飞行m距离前提下n选k最大(向前看 dp)

    藏宝图中标注了N个宝库的位置。这N个宝库连成了一条直线,每个宝库都有若干枚金币。X星人决定乘坐热气球去收集金币,热气球每次最多只能飞行M千米,此外,热气球最多只能启动K次。X星人带着热气球来到了第1个宝库(达到第1个宝库时热气球尚未启动),收集完第1个宝库的金币后将启动热气球前往下一个宝库。如果他决定收集某一个宝库的金币,必须停下热气球,收集完之后再重新启动热气球。当然,X星人每到一个宝库是一定会拿走这个宝库所有金币的。已知每一个宝库距离第1个宝库的距离和宝库的金币数量。请问X星人最多可以收集到多少枚金币?
    输入描述
    第1行三个正整数N、M和K,分别表示宝库的数量、热气球每次最多能够飞行的距离(千米)和热气球最多可以启动的次数,三个数<100
    接下来N行分别表示第1个宝库到某一个宝库的距离(千米)和这个宝库的金币枚数。保证所有的宝库按照到第1个宝库的距离从近到远排列,初始位置为第1个宝库。
    输出描述
    输出一个正整数,表示最多可以收集的金币数。

    样例输入
    5 10 2
    0 5
    8 6
    10 8
    18 12
    22 15
    样例输出
    25
    提示
    X星人启动热气球两次,分别收集第1个、第3个和第4个宝库的金币,一共可以得到的金币总数为5+8+12=25枚。
    

    思路:f[i][j]表示对于前i个宝藏,重启j次能拿到最多多少个硬币

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int N=105;
    struct node{
        int d,c;
    }A[N];
    int f[N][N];
    int main() {
        std::ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
        int n,m,k; cin>>n>>m>>k;
        for (int i=1; i<=n; i++) cin>>A[i].d>>A[i].c;
        for (int i=1; i<=k; i++) f[1][i]=A[1].c;
        for (int i=1; i<=n; i++) f[i][0]=A[1].c;
        
        int ans=0;
        for (int i=2; i<=n; i++)
        for (int j=1; j<=k; j++) {
            if (A[i].d <= j*m) {
                int pre=i-1;
                while (pre && A[i].d-A[pre].d <= m) {
                    f[i][j]=max(f[i][j], f[pre][j-1]+A[i].c);
                    pre--;
                }
                ans=max(ans, f[i][j]);
            }
        }
        cout<<ans;
        return 0;
    }
    
  • 相关阅读:
    Linux上ssh免秘钥互登
    Linux版本显示和区别32位还是64位系统
    shell运行下的写日志
    oracle 分析函数
    oracle解锁
    Linux下的打包操作
    python 小记
    Python 之 random模块
    JS模块化工具requirejs教程02
    JS模块化工具requirejs教程01
  • 原文地址:https://www.cnblogs.com/wdt1/p/14590541.html
Copyright © 2011-2022 走看看