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; }