SGU 104 Little shop of flowers【DP】
4483 ワード
波(食べる)一日、水道の问题は冷静で冷静です....
タイトルリンク:
http://acm.sgu.ru/problem.php?contest=0&problem=104
タイトル:
各花を各植木鉢に置く値を指定して、番号の大きい花は番号の小さい花の後ろに置くしかなくて、各花はすべて植木鉢の中に置いて、どのように置いて総額を最大にすることができますか?
分析:
やはり水のdpを比較して...各位置には2つの状況があります:放すか放さないか.置かないとdp[i][j−1][0]は前の最近の植木鉢が置かれた値に等しい.放すと、dp[i][j][1]が更新されます.これにより、各植木鉢i花jに対して、max(dp[i−1][j−1][0],dp[i−1][j−1][1])がj−1番花を置いた後に得られる最大の値を示すことが保証される.最後に逆押ししてパスを取得すればいいです.
コード:
タイトルリンク:
http://acm.sgu.ru/problem.php?contest=0&problem=104
タイトル:
各花を各植木鉢に置く値を指定して、番号の大きい花は番号の小さい花の後ろに置くしかなくて、各花はすべて植木鉢の中に置いて、どのように置いて総額を最大にすることができますか?
分析:
やはり水のdpを比較して...各位置には2つの状況があります:放すか放さないか.置かないとdp[i][j−1][0]は前の最近の植木鉢が置かれた値に等しい.放すと、dp[i][j][1]が更新されます.これにより、各植木鉢i花jに対して、max(dp[i−1][j−1][0],dp[i−1][j−1][1])がj−1番花を置いた後に得られる最大の値を示すことが保証される.最後に逆押ししてパスを取得すればいいです.
コード:
#include<cstdio>
#include<iostream>
#include<stack>
#include<cstring>
using namespace std;
const int maxn = 100 + 5;
int dp[maxn][maxn][2];
int v[maxn][maxn];
stack<int>s;
int main (void)
{
int n, m;
scanf("%d%d", &m, &n);
for(int i = 1; i <= m; i++){
for(int j = 1; j <= n; j++){
scanf("%d", &v[i][j]);
}
}
memset(dp, -0x3f, sizeof(dp));
dp[0][0][0] = 0;
for(int i = 1; i <= n; i++){
for(int j = 1; j <= m; j++){
dp[i][j - 1][0] = max(dp[i - 1][j - 1][0] ,dp[i - 1][j - 1][1]);
dp[i][j][1] = max(dp[i - 1][j - 1][0], dp[i - 1][j - 1][1]) + v[j][i];
}
}
int ans = max(dp[n][m][1], dp[n][m][0]);
printf("%d
", ans);
int sta = n;
for(int i = m; i >= 0; i--){
for(int j = sta; j >= 0; j--){
if(dp[j][i][1] == ans && ans){
s.push(j);
sta = j - 1;
ans -= v[i][j];
break;
}
}
}
while(!s.empty()){
int res =s.top();
s.pop();
printf("%d ", res);
}
printf("
");
return 0;
}