SGU 104 DP

题目链接点这儿

题意就是给个矩阵,每一行选一个值,保证第 i 行的的值的位置 j 要在第 i+1 行选的组织的位置j'之前。(j < j')

所以就用dp做啦,dp[i][j]表示选到第j列为止,已经选了前i个数(就是选数活动进行到了第i行第j列) 状态转移方程

dp[i][j] = max(dp[i][j-1], dp[i-1][j-1] + value[i][j]) (value[i][j] 表示矩阵在i行j列处的值)

题目还有一个要求是记录你选的位置。。。这个网上有各种方法。。。但是都写的比较多。。。我图省事直接上了vector记录。。。代码长度上是很短的。。而且操作起来确实省事。。。就是费内存。。。

对了dp[i][j]初始化时不能是0.。。因为矩阵中值可能为负数。。。我就因为这个。。。把sgu的online status的第一页给全占了。。

下面是代码

#include <bits/stdc++.h>
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)>(b)?(b):(a))
#define rep(i,initial_n,end_n) for(int (i)=(initial_n);(i)<(end_n);i++)
#define repp(i,initial_n,end_n) for(int (i)=(initial_n);(i)<=(end_n);(i)++)
#define reep(i,initial_n,end_n) for((i)=(initial_n);(i)<(end_n);i++)
#define reepp(i,initial_n,end_n) for((i)=(initial_n);(i)<=(end_n);(i)++)
#define eps 1.0e-9
#define MAX_N 500

using namespace std;
typedef pair<int, int> pii;
typedef pair<double, double> pdd;
typedef long long ll;
typedef unsigned long long ull;

int dp[110][110] = { { 0 } }, n, m, martix[110][110];
vector<int> ans[110][110];

int main() {
    scanf("%d%d", &n, &m);
    repp(i, 1, n) repp(j, 1, m) scanf("%d", &martix[i][j]);
    repp(i, 1, n) {
        dp[i][i-1] = INT_MIN;
        repp(j, i, m) {
            if(dp[i-1][j-1] + martix[i][j] > dp[i][j-1]) {
                dp[i][j] = dp[i-1][j-1] + martix[i][j];
                ans[i][j] = ans[i-1][j-1];
                ans[i][j].push_back(j);
            }
            else
                dp[i][j] = dp[i][j-1], ans[i][j] = ans[i][j-1];
        }
    }
    printf("%d\n", dp[n][m]);
    rep(i, 0, n) printf("%d%c", ans[n][m][i], i == n - 1 ? '\n' : ' ');
    return 0;
}


你可能感兴趣的:(算法,dp,ACM)