洛谷: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.