1. 问题
有n个项目,m元钱,dp[x,y]表示第x个项目投资y元钱的效益,问如何投资使效益最大。
2. 解析
这其实是个很简单的问题,第x个项目投资y元,若当前投资额为m元,则他是从第x-1个项目投资额为m-y元转移过来
则dp[x][y]//x表示第x个项目,y表示当前投资额
Dp方程:dp[x][y]=max(dp[x][y],dp[x-1][y-t]+a[x][t]//x表示项目数,y表示投资额,t表示第x项目投资金额
3. 设计
for (int i = 1; i <= n; i++) {
for (int j = 0; j <= m; j++) {
dp[i][j] = 0;
for (int k = 0; k <= j; k++) {
if (dp[i][j] < a[i][k] + dp[i - 1][j - k]) {
dp[i][j] = a[i][k] + dp[i - 1][j - k];
}
}
}
}
4. 分析
复杂度 O(n3)
5. 源码
https://github.com/Tinkerllt/algorithm-work.git
#include<stdio.h>
#include<iostream>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<bitset>
#include<set>
#include<deque>
#include<queue>
#include<vector>
//#include<unordered_map>
#include<map>
#include<stack>
using namespace std;
#define ll long long
#define ull unsigned long long
#define pii pair<int,int>
#define Pii pair<ll,int>
#define m_p make_pair
#define l_b lower_bound
#define u_b upper_bound
const int inf = 0x3f3f3f3f;
const ll linf = 0x3f3f3f3f3f3f3f3f;
const int maxn = 300 + 11;
const int maxm = 600 + 11;
const int mod = 1e9 + 7;
const double eps = 1e-5;
ll rd() { ll x = 0, f = 1; char ch = getchar(); while (ch<'0' || ch>'9') { if (ch == '-')f = -1; ch = getchar(); }while (ch >= '0'&&ch <= '9') { x = x * 10 + ch - '0'; ch = getchar(); }return x * f; }
inline ll qpow(ll a, ll b, ll p) { ll res = 1; while (b) { if (b & 1) { res *= a; res %= p; }b >>= 1; a = a * a%p; }return res; }
inline ll gcd(ll a, ll b) { if (b == 0) return a; return gcd(b, a%b); }
//iterator
//head
//priority_queue
int a[maxn][maxn], dp[maxn][maxn];
int main() {
int n,m;
while (cin>>n>> m) {
for (int i = 1; i <= n; i++) {
a[i][0] = 0;
for (int j = 1; j <= m; j++)
scanf("%d", &a[i][j]);
}
for (int i = 1; i <= n; i++) {
for (int j = 0; j <= m; j++) {
dp[i][j] = 0;
for (int k = 0; k <= j; k++) {
if (dp[i][j] < a[i][k] + dp[i - 1][j - k]) {
dp[i][j] = a[i][k] + dp[i - 1][j - k];
}
}
}
}
printf("%d
", dp[n][m]);
}
return 0;
}