zoukankan      html  css  js  c++  java
  • 成环间隔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;
    }
  • 相关阅读:
    Teacher Bo HDU 5762(暴力)
    The Unique MST POJ1679(次小生成树)
    Sqrt Bo hdu 5752
    Borg Maze POJ 3026(BFS+最小生成树)
    Highways POJ 1751(最小生成树)
    hdu---2050---折线分割平面
    POj---1469---Courses
    poj---2349---Arctic Network
    poj-2528-Mayor's posters
    POJ---3468---A Simple Problem with Integers
  • 原文地址:https://www.cnblogs.com/MorrowWind/p/13056382.html
Copyright © 2011-2022 走看看