您的位置:首页 > 其它

花店橱窗 (dp-路径记录)

2018-03-09 21:46 134 查看


第一问很简单。

f[i][j]表示前i朵花放在前j个花瓶里时的最大美学值,且此时第i朵花必须放在第j个花瓶里。则有状态转移方程:

f[i][j]=max(f[i-1][k]+a[i][j]) ( i-1<=k<=j-1)

k范围限制是因为至少已经有前i-1个花瓶放了花。

第二问记录每次决策。可以用递归写,有机会(没有)试试。这里采用的方法是,声明一个 pre[i][j] ,记录是由 f[i-1] 的哪个状态得到f[i][j]的最优值。

void init()
{
memset(a,0,sizeof(a));
read(F);read(v);
for(int i=1;i<=F;++i)
for(int j=1;j<=v;++j)
read(a[i][j]),f[i][j]=-2e9;//初始全部为不合法,因为不是每个花瓶都放花的。
}

void work()
{
for(int i=1;i<=F;++i) f[0][i]=0;
for(int i=1;i<=F;++i)
for(int j=i;j<=v-F+i;++j)// 至少要留下F-i个花瓶给剩下的花。
for(int k=i-1;k<=j-1;++k)
if(f[i-1][k]+a[i][j]>f[i][j])
{
pre[i][j]=k;//记录前驱。
f[i][j]=f[i-1][k]+a[i][j];
}
ans=0;
for(int i=1;i<=v;++i)
if(ans<f[F][i]) ans=f[F][i],Ans[F]=i;//先找到最大美学值,其对应的j也是第F朵fafa所放的花瓶。
printf("%d\n",ans);
for(int i=F;i>=2;--i)
Ans[i-1]=pre[i][Ans[i]];//Ans[i]表示第i朵花放的花瓶j,它的前驱即是第i-1朵花的选择。
for(int i=1;i<F;++i) printf("%d ",Ans[i]);
printf("%d",Ans[F]);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: