您的位置:首页 > 其它

RQNOJ 花店橱窗布置

2013-05-24 00:34 316 查看
点击打开链接

思路: 动态规划

分析:

1 题目要求找到最大的美学值,并且要求标识号大的必须在标识号小的右边,那么这就可以知道,如果花朵i在第i行的第j列那么第i+1朵必须在j+1后面

2 很明显的阶段就出来了,我们用dp[i][j]表示第i朵花放在第j列能够得到的最大美学值,那么dp[i][j] = max(dp[i-1][j]) + num[i][j];这里注意每一多花可以放的区间,第i多花可以放的区间就是第i行的[i~V-F+n]

3 题目要求输出没多花的位置,那么就是在状态转移的时候记录一下位置即可

代码:

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;

const int INF = 1<<30;
const int MAXN = 110;

int n , m;
int num[MAXN][MAXN] , dp[MAXN][MAXN];
int path[MAXN][MAXN] , output[MAXN];

void solve(){
for(int i = 1 ; i <= m-n+1 ; i++)
dp[1][i] = num[1][i];
memset(path , -1 , sizeof(path));
for(int i = 2 ; i <= n ; i++){
for(int j = i ; j <= m-n+i ; j++){
dp[i][j] = num[i][j];
int Max = -INF;
int pos;
for(int k = i-1 ; k < j ; k++){
if(dp[i-1][k] > Max){
Max = max(Max , dp[i-1][k]);
pos = k;
}
}
dp[i][j] += Max;
path[i][j] = pos;
}
}
int ans = -INF;
int pos , x , y;
for(int i = n ; i <= m ; i++){
if(ans < dp
[i]){
ans = max(ans , dp
[i]);
y = i;
}
}
printf("%d\n" , ans);
pos = n-1;
x = n;
output[pos--] = y;
while(path[x][y] != -1){
output[pos--] = path[x][y];
y = path[x--][y];
}
printf("%d" , output[0]);
for(int i = 1 ; i < n ; i++)
printf(" %d" , output[i]);
printf("\n");
}

int main(){
while(scanf("%d%d" , &n , &m) != EOF){
for(int i = 1 ; i <= n ; i++)
for(int j = 1 ; j <= m ; j++)
scanf("%d" , &num[i][j]);
solve();
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: