[교육] 그룹화 알고리즘 배낭 문제

N 항목 V 및 배낭의 용량, [I]는 V의 값이 [I]은, 항목이 다수의 그룹으로 분할되고, 충돌 항목의 각 그룹이 가장으로부터 선택된 W의 i 번째 항목의 중량있다 하나는
배낭에 항목이 최고의 가치를 얻을 수있는 배낭을 일으킬 수있는 질문

각 항목 군 번 처리 될 수있는 항목에 대해 각 그룹에 대해, 이는하는 01 배낭 문제로 간주 될 수있다.

입력 형식 :
첫 번째 줄 세 정수, V (배낭 용량, V <= 200), N ( 항목 수, N <= 30) 및 T (최대 그룹 번호, T <= 10),
제 2 ... N + 라인 1 : 무선는 VI가, P는 가중치를 나타내고, 세 개의 정수의 각 행은, 각 항목의 그룹 번호에 속한다.
로부터 참조이 블로그의 아이디어
블로그 참조
형태의 2 차원 배열의 성능 경우 :

  1. 그룹 순환의 수
  2. 선택 항목
  3. 볼륨주기
    // 二维数组:
    f[k][j]表示前k组体积为j的最大价值
    for(int k=1; k<=T; ++k)            //组别
        for(int i=1; i<=N; ++i)       //物品
            for(int j=V; j>=0; j--)   //体积
                f[k][j] = max(f[k][j], v[k][i]+f[k-1][j-w[k][i]] );  //求组这组最大

하며, f[k-1][j]따라서 최대 값 J 볼륨 그룹 전에-1 K, 및 참조하면 v[k][i] + f[k-1][j-w[k][i]]수단 : 제 i + K-1 문서 볼륨 그룹 JW [K] 전에 현재 세트를 복용 [I] (왼쪽 버튼의 볼륨 제품) 값의 볼륨의 현재 값 밖으로.

한 차원 단어 :

  1. 패킷 그룹의 수
  2. 볼륨주기
  3. 제품의 순회
    // 一维数组 :f[j]表示体积为j的时候的最大价值!(每组都共用一个dp数组,dp数组保存最大价值)
    for(int k=1; k<=T;k++)
        for(int j=V; j>=0; j--)   //分组体积
            for(int i=1; i<=a[k][0]; i++){  //对体积里的每个物品
                int x = a[k][i]; //x来记录物品编号
                if(j>=w[i])  //容量大于第i个物品的体积
                    f[j] = max(f[j], v[x]+f[j-w[x]] ); //价值为
            }

그 중 다음과 같은 일반은 1 차원 배열의 형태를했다.
코드 입력 값을 참조 할 수 있습니다 이 블로그

#include<iostream>
#include<algorithm>
#include <vector>
#include<cstring> 
using namespace std;
const int maxn=105;
const int maxv=105;
const int maxt=15;
int N,V,T;
int v[maxn], w[maxn];
int dp[maxv]; //f存的是代价函数,因此以v为单位,f的意思是容量为c时该组取所需元素的最大值
int groupitem[maxt][maxn]; //a存放的是分组t里的物品编号

int main(){

    cin>>V>>N>>T;
   memset(&groupitem, 0, sizeof(groupitem)); //这一步似乎可有可无

    // 输入
    for(int i=1; i<=N; ++i){
        int p;
        cin>>w[i]>>v[i]>>p;
        groupitem[p][++groupitem[p][0]] = i;  //groupitem[p][0]来存放该组的数量
    }

    // 开始求解,分别是①对组;②对每组来说的容量;③对该组内的物品进行~
    for(int i=1; i<=T; ++i){
        for(int j=V; j>=0; --j)
            for(int k=1; k<=groupitem[i][0]; k++){
                int x = groupitem[i][k]; // 获取当前组的物品编号
                //记得if语句判断一下:
                if( j>=w[x] )
                    dp[j] = max(dp[j], v[x] + dp[j-w[x]]); //一维的写法,  关键是f[j-w[x]]去掉
            }
    }
    cout<<dp[V]<<endl; //从而输出:容量为j的时候

    return 0;

}


게시 63 개 원래 기사 · 원 찬양 13 ·은 40000 +를 볼

추천

출처blog.csdn.net/changreal/article/details/102582162