投资问题

dp的经典题目吧。。求出一个最大值还是挺简单的,而且范围没有很大。。
题目描述:
n个投资项目, r份资源
对于每一个投资项目输入r + 1个数分别表示投资r[i]时的收益,范围[0, r]
对每一个项目选择投资数量,最后输出收益的最大值。
SAMPLE INPUT:
3 8
0 4 26 40 45 50 51 52 53
0 5 15 40 60 70 73 74 75
0 5 15 40 80 90 95 98 100

4 6
0 20 50 65 80 85 85
0 20 40 50 55 60 65
0 25 60 85 100 110 115
0 25 40 50 60 65 70

SAMPLE OUTPUT
140
160

代码:

/*
 *
 *  Author : Triose
 *  Email  : Triose@163.com
 *  Update_time : 2016.6.12
 *
 */


//#include<bits/stdc++.h>
#include<stdio.h>
#include<iostream>
#include<string>
#include<string.h>
#include<algorithm>
#include<vector>
#include<queue>
#include<stack>
#include<iterator>
#include<math.h>
#include<bitset>
#include<stdlib.h>
#include<time.h>
#include<map>
#include<set>
using namespace std;
//#define ONLINE_JUDGE
#define eps 1e-8
#define inf 0x3f3f3f3f
#define INF 0x7fffffff
#define INFL 0x3f3f3f3f3f3f3f3fLL
#define enter putchar(10)
#define rep(i,a,b) for(int i = (a); i < (b); ++i)
#define repe(i,a,b) for(int i = (a); i <= (b); ++i)
#define mem(a,b) (memset((a),b,sizeof(a)))
#define sf(a) scanf("%d",&a)
#define sfI(a) scanf("%I64d",&a)
#define sfd(a,b) scanf("%d%d",&a,&b)
#define sft(a,b,c) scanf("%d%d%d",&a,&b,&c)
#define sfs(a) scanf("%s",a)
#define pf(a) printf("%d\n",a)
#define pfd(a,b) printf("%d %d\n",a,b)
#define pfP(a) printf("%d %d\n",a.fi,a.se)
#define pfs(a) printf("%s\n",a)
#define pfI(a) printf("%I64d\n",a)
#define PR(a,b) pair<a,b>
#define fi first
#define se second
#define LL long long
#define DB double
const double PI = acos(-1.0);
const double E = exp(1.0);
template<class T> T gcd(T a, T b) { return b ? gcd(b, a % b) : a; }
template<class T> T lcm(T a, T b) { return a / gcd(a, b) * b; }
template<class T> inline T Min(T a, T b) { return a < b ? a : b; }
template<class T> inline T Max(T a, T b) { return a > b ? a : b; }

const int maxr = 25;
const int maxn = 15;

int a[maxn][maxr];
int n, r;
int dp[maxn][maxr][maxr]; // 第i个投j份剩余k份


void Init() {
    memset(dp, 0, sizeof(dp));
    for(int i = 1; i <= n; i++) for(int j = 0; j <= r; j++) cin >> a[i][j];
    for(int j = 0; j <= r; j++) dp[1][j][r - j] = a[1][j];
}

int solve() {
    for (int i = 2; i <= n; i++) for (int j = 0; j <= r; j++)
        for (int k = 0; k <= r; k++) {
            int tmp = 0;
            repe(x, 0, r - k - j) tmp = Max(tmp, dp[i - 1][x][k + j]);
            dp[i][j][k] = tmp + a[i][j];
        }

    int ret = 0;
    for (int i = 0; i <= r; i++) for (int j = 0; j <= r; j++)
        ret = Max(ret, dp[n][i][j]);
    return ret;
}


int main() {
#ifndef ONLINE_JUDGE
    freopen("in.txt","r",stdin);
//  freopen("Out.txt", "w", stdout);
#endif
    ios::sync_with_stdio(false);
    while (cin >> n >> r) {
        Init();
        cout << solve() << "\n";
    }
    return 0;
}

直观的描述就是这样把, 数据范围小,没考虑时空复杂度的问题。
我觉得吧,应该还有简化得办法。。。说不定能压缩一维啊啥的,或者复杂度能降低啊啥的,待补充

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值