1. 程式人生 > >洛谷:P1853 【投資的最大效益】

洛谷:P1853 【投資的最大效益】

題目背景

約翰先生獲得了一大筆遺產,他暫時還用不上這一筆錢,他決定進行投資以獲得更大的效益。銀行工作人員向他提供了多種債券,每一種債券都能在固定的投資後,提供穩定的年利息。當然,每一種債券的投資額是不同的,一般來說,投資越大,收益也越大,而且,每一年還可以根據資金總額的增加,更換收益更大的債券。

題目描述

例如:有如下兩種不同的債券:①投資額$4000,年利息$400;②投資額$3000,年利息$250。初始時,有$10000的總資產,可以投資兩份債券①債券,一年獲得$800的利息;而投資一份債券①和兩份債券②,一年可獲得$900的利息,兩年後,可獲得$1800的利息;而所有的資產達到$11800,然後將賣掉一份債券②,換購債券①,年利息可達到$1050;第三年後,總資產達到$12850,可以購買三份債券①,年利息可達到$1200,第四年後,總資產可達到$14050。

現給定若干種債券、最初的總資產,幫助約翰先生計算,經過n年的投資,總資產的最大值。

輸入輸出格式

輸入格式:

第一行為三個正整數s,n,d,分別表示最初的總資產、年數和債券的種類。

接下來d行,每行表示一種債券,兩個正整數a,b分別表示債券的投資額和年利息。

輸出格式:

僅一個整數,表示n年後的最大總資產。

我們先分析一下題目: 對於第一年,可以將第一年的錢儘可能地拿去投資,然後獲得能夠得到的最大利息;然後對於第二年,第二年可以使用的金錢相當於第一年的初始金錢加上利息,然後再用這些錢儘可能地拿去投資,獲得能夠得到的最大利息...於是,第i年時就可以將第i-1年投資所得到的利息再加上第i-1年的初始金錢儘可能拿去投資,獲得能夠得到的最大金錢.於是第n年就很容易地推導了出來. 那麼對於這些操作,我們只需要將一個完全揹包放入一個n層的迴圈裡,然後每層迴圈結束後對完全揹包的第二層迴圈的上限進行更新,經過n次迴圈就可以得出答案了.

#include <iostream>
#include <cstring>
#define maxs 1000000 + 5
#define maxn 40 + 5
#define maxd 10 + 5
#define maxm 10000000 + 5
#define inf 0x80808080
using namespace std;

int c[maxd], t[maxd];
int s, n, d;
int dp[maxm];

int main(){
    ios::sync_with_stdio(false);
    cin >> s >> n >> d;
    for(int i = 1; i <= d; i++) cin >> c[i] >> t[i];

    for(int i = 1; i <= n; i++){
        for(int j = 1; j <= d; j++){
            for(int k = c[j]; k <= s - s % 1000; k += 1000){
                if(dp[k] < dp[k - c[j]] + t[j]){
                    dp[k] = dp[k - c[j]] + t[j];
                }
            }
        }
        s += dp[s - s % 1000];
    }
    cout << s << endl;

    return 0;
}

另外,由於題目說每種債劵的投資額都是1000的倍數,所以在完全揹包的第二層迴圈中變數可以 -= 1000.