花店橱窗布置
题目链接:https://www.luogu.com.cn/problem/P1854
题意:
给定f朵花,v个花瓶(v>=f)
每朵花在不同花瓶都有不同的权值
规定每朵花的相对次序不能改变
求将所有花都塞入花瓶时的最大权值和以及获得其的路径
思路:
记dp[i][j]:第i朵花塞入第j个瓶子时的最大权值和
显然需要从上一朵花转移得到
极限情况下第i朵花塞入瓶子编号最小值为i,最大为v
dp[i][j]=max(dp[i][j],dp[i-1][p]+g[i][j])
其中p的范围为[i-1,j-1],保证相对次序
另外dp数组初始化时考虑权值和有可能是负的,所以除了dp[0][i]都为-inf
对于求路径问题,需要开一个pre二维数组
对于每一个(i,j),转移权值最大时pre[i][j]就指向的是(i-1,temp)这个位置
int g[105][105];
int pre[105][105];
int dp[105][105];
int path[105];
void solve(){
int f,v;cin>>f>>v;
memset(dp,-inf,sizeof dp);
rep(i,1,f){
rep(j,1,v){
cin>>g[i][j];
}
}
rep(i,0,v){
dp[0][i]=0;
pre[0][i]=-1;
}
for(int i=1;i<=f;i++){
for(int j=i;j<=v;j++){
for(int p=i-1;p<j;p++){
if(dp[i][j]<dp[i-1][p]+g[i][j]){
dp[i][j]=dp[i-1][p]+g[i][j];
pre[i][j]=p;
}
}
}
}
int big=-inf;
int temp=-1;
for(int i=f;i<=v;i++){
if(big<dp[f][i]){
big=dp[f][i];
temp=i;
}
}
cout<<big<<endl;
int pos=f;
vector<int>ans;
while(pos!=0){
ans.pb(temp);
temp=pre[pos][temp];
pos--;
}
for(int i=ans.size()-1;i>=0;i--){
cout<<ans[i]<<' ';
}
}

浙公网安备 33010602011771号