sgu 104. Little shop of flowers (dp+记录dp的结果)

SGU 104. Little shop of flowers: http://acm.sgu.ru/problem.php?contest=0&problem=104

题意:给你F支花和V个花瓶,再给出一个F*V的矩阵,表示第i支花插到第j个瓶子所得到的魅力值,插花的时候有两个规则

1.编号小的花一定要放在编号大的花的前面。 2.所有花全部都要放完。 

问所能达到的最大的魅力值及达到此魅力值的放置方法。

思路:使用动态规划的方法。

dp定义:dp[i][j] 将剩下的第i~F支花插入到第j~V个花瓶上时的最大值

dp转移方程:dp[i][j]=max(dp[i][j],dp[i+1][k+1]+cc[i][k])  j<=k<=V-(F-i-1)(保证每个花都有位置放)

用这个dp的方法可以求出来最大值,但是该如何输出放置的方法呢?

对于一般的dp问题的方案输出,我们可以用一个数组来记录他是又哪一个状态转移过来的,这样的迭代下去我们就能知道最优的方案了~~~~。

code:

#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <cstring>
#define INF 100000000

using namespace std;

const int maxn=200;

int dp[maxn][maxn];
int fp[maxn][maxn];
int cc[maxn][maxn];
int F,V;

int dfs(int x,int y)
{
    if(x>=F) return 0;
    if(y>=V) return -INF;
	if(dp[x][y]!=0) return dp[x][y];
	int res=0,pos=-1;
	for(int k=y;k<V-(F-x-1);k++){
		if(dfs(x+1,k+1)+cc[x][k]>=res){
			res=dp[x+1][k+1]+cc[x][k];
			pos=k;
		}
	}
	dp[x][y]=res;
	fp[x][y]=pos;
	return dp[x][y];
}

int main()
{
	int pos;
	while(scanf("%d%d",&F,&V)!=EOF){
		for(int i=0;i<F;i++) for(int j=0;j<V;j++){scanf("%d",&cc[i][j]); cc[i][j]+=50;}
		memset(dp,0,sizeof(dp));
		memset(fp,-1,sizeof(fp));
		printf("%d\n",dfs(0,0)-F*50);
		pos=fp[0][0];
		printf("%d",pos+1);
		for(int i=1;i<F;i++){
			pos=fp[i][pos+1];
			printf(" %d",pos+1);
		}
		printf("\n");
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值