1005 花店橱窗 线性DP 动态规划
来源:牛客网
题目描述
小q和他的老婆小z最近开了一家花店,他们准备把店里最好看的花都摆在橱窗里。
但是他们有很多花瓶,每个花瓶都具有各自的特点,因此,当各个花瓶中放入不同的花束时,会产生不同的美学效果。
为了使橱窗里的花摆放的最合适,他们得想个办法安排每种花的摆放位置。
可是因为小q和小z每天都太忙,没有时间设计橱窗里花的摆法,所以他们想让你帮他们求出花摆放的最大美观程度和每种花所放的位置。
每种花都有一个标识,假设杜鹃花的标识数为1,秋海棠的标识数为2,康乃馨的标识数为3,所有的花束在放入花瓶时必须保持其标识数的顺序,即:
杜鹃花必须放在秋海棠左边的花瓶中,秋海棠必须放在康乃馨左边的花瓶中。
如果花瓶的数目大于花束的数目。则多余的花瓶必须空置,且每个花瓶中只能放一束花。
每种花放在不同的瓶子里会产生不同的美观程度,美观程度可能是正数也可能是负数。
上述例子中,花瓶与花束的不同搭配所具有的美观程度,如下表所示:
花 瓶 1 2 3 4 5 1 (杜鹃花) 7 23 -5 -24 16 2 (秋海棠) 5 21 -4 10 23 3 (康乃馨) -21 5 -4 -20 20
根据上表,杜鹃花放在花瓶2中,会显得非常好看;但若放在花瓶4中则显得十分难看。
为取得最大美观程度,你必须在保持花束顺序的前提下,使花束的摆放取得最大的美学值,并求出每种花应该摆放的花瓶的编号。
输入描述:
第1行:两个整数F和V,表示共有F种花,V个花瓶。
第2行到第F+1行:每行有V个数,表示花摆放在不同花瓶里的美观程度值value。(美观程度和小于2312^{31}231,美观程度有正有负)
输出描述:
输出有两行:第一行为输出最大美观程度和的值,第二行有F个数表示每朵花应该摆放的花瓶的编号。
若有多种方案,输出字典序较小的方案(美观程度不变的情况下,花尽量往前放)。
备注:
F<100,V<100
分析
类似数字三角形
每个位置的dp值要么从左上角来(同列还没摆好),要么从左边来(同列已经摆好了),要么从上面来(同列还没摆好)
状态转移方程:
dp[i][j] 表示 第i行第j个的最好情况
如果已经有了 dp[i][j]能从左边转移也就是 dp[i][j-1] ,也能从左上角转移dp[i-1][j-1] + a[i][j];
如果没有,dp[i][j] = dp[i-1][j-1] + a[i][j]
//-------------------------代码----------------------------
//#define int LL
const int N = 200;
int n,m;
int dp[N][N];
int path[N];
int a[N][N];
void solve()
{
cin>>n>>m;
fo(i,1,n) {
fo(j,1,m) {
cin>>a[i][j];
}
}
fo(i,1,n) {
fo(j,i,m) {
if(i == j) {
dp[i][j] = dp[i-1][j-1] + a[i][j];
} else {
dp[i][j] = max(dp[i][j-1],dp[i-1][j-1] + a[i][j]);
}
}
}
cout<<dp[n][m]<<endl;
while(n) {
while(dp[n][m] == dp[n][m-1]) {
m -- ;
}
path[n] = m;
n -- ;
m -- ;
}
for(n = 1;path[n];n ++ ) {
cout<<path[n]<<' ';
}
}
signed main(){
clapping();TLE;
// int t;cin>>t;while(t -- )
solve();
// {solve(); }
return 0;
}
/*样例区
*/
//------------------------------------------------------------