hdu3033(分组背包)

    xiaoxiao2022-07-07  191

    分组背包其实是01背包的思想,因为虽然有多组,但实际上每次也是考虑单个是选择还是不选择的问题,只是多了个组别而已,各组看成是独立的,根据题意建立状态转化方程。 http://acm.hdu.edu.cn/showproblem.php?pid=3033 设置一个动态数组dp【i】【j】表示此时j元买前i种鞋最大价值(给鞋编种类从1到K);

    //#include<bits/stdc++.h> #include<iostream> #include<cstring> #include<string> using namespace std; const int inf = 0x3f3f3f3f; int weight[15][150]; int val[15][150]; int dp[105][10005]; int max(int a,int b) { if(a>b)return a; else return b; } int main() { ios::sync_with_stdio(false); cin.tie(0); int N,M,K; while(cin>>N>>M>>K) { int a,b,c; int a1[11]; //int b1[11]; int bb[11]; memset(bb,0,sizeof(bb)); for(int i=0;i<N;i++) { cin>>a>>b>>c; weight[a][++bb[a]]=b; val[a][bb[a]]=c; } for(int i=0;i<=K;i++) for(int j=0;j<=M;j++) { if(i==0)dp[i][j]=0; else dp[i][j]=-inf;//给每一个初始化为最小负数 } //for(int i=1;i<=K;i++) //for(int j=1;j<=bb[i];j++) //cout<<"i="<<i<<"j="<<j<<endl; for(int i=1;i<=K;i++) for(int j=1;j<=bb[i];j++) for(int k=M;k>=weight[i][j];k--) { int v=k-weight[i][j]; dp[i][k]=max(dp[i][k],max(dp[i-1][v]+val[i][j],dp[i][v]+val[i][j]));//若dp[i][k]<0说明,dp[i-1][v]<0(注意:一开始初始时是最小的负数,则现在依然是很小的负数,可以看着加上任何范围内的正数后依然是负数)说明v元无法买前(i-1)种鞋,说明dp[i][v]<0说明v元也无法买前i种鞋,说明dp[i][k]<0,即转态转化后依然是k元无法买前i种鞋 } if(dp[K][M]<0)//小于0说明M元无法买K种鞋 cout<<"Impossible"<<endl; else cout<<dp[K][M]<<endl; } } 在这里插入代码片
    最新回复(0)