成环间隔01背包
Posted morrowwind
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了成环间隔01背包相关的知识,希望对你有一定的参考价值。
#include <bits/stdc++.h> using namespace std; //算法提高 种树 //这是01背包问题的变形 //环的处理方法 1.找到最小值的位置,预处理数组,比如 56 21 64 32 45 -> 21 64 32 45 56 21 //这样就相邻了而且21 21肯定不会同时选到 //2.还可以:第一个和最后一个只会选一个, //那么就对 1...n-1 2...n进行处理,然后求最大值,注意要求两次dp,不是一次完成 int dp[101][101]={0},n,m,a[101][101]={0},v[101],v1[101]; int main() { int min=1; cin>>n>>m; for(int i=1;i<=n;i++) { cin>>v1[i]; if(v1[i]<v1[min]) min=i; } if(n/2<m) {cout<<"Error! ";return 0;} for(int i=min;i<=n;i++) v[i-min+1]=v1[i]; for(int i=1;i<=min;i++) v[n-min+i+1]=v1[i]; n++; dp[n][1]=v[n]; a[n][1]=n; //这个是定义a的做法,a存放对应的dp数组的最左边位置的index // for(int i=n-1;i>=1;i--){ // for(int j=1;j<=m;j++){ // if(j>(n-i+1)/2) continue; // if(dp[i+1][j]>dp[i][j]){ // dp[i][j]=dp[i+1][j]; // a[i][j]=a[i+1][j]; // } // if(a[i+2][j-1]!=i+1){ // if(dp[i+2][j-1]+v[i]>dp[i][j]){ // dp[i][j]=dp[i+2][j-1]+v[i]; // a[i][j]=i; // } // } // } // } //也可以不定义a,因为dp[i+2][j-1]已经代表着不相邻了。 for(int i=n-1;i>=1;i--){ for(int j=1;j<=m;j++){ if(j>(n-i+1)/2) continue; dp[i][j]=max(dp[i+1][j],dp[i+2][j-1]+v[i]); } } cout<<dp[1][m]<<endl; return 0; }
以上是关于成环间隔01背包的主要内容,如果未能解决你的问题,请参考以下文章
代码随想录算法训练营第四十二天 | 01背包问题,你该了解这些01背包问题,你该了解这些 滚动数组 416. 分割等和子集