分析:dp[l][i][j][k]表示选前l件时花费i元,积分j,免费p时能获得的最大价值。k值也作为一种背包算。
状态转移方程:
dp[l][i][j][k] = max(dp[l][i][j][k], dp[l-1][i-a[l]][j][k]+c[i], dp[l-1][i][j-b[l]][k]+c[i], dp[l-1][i][i][k-1]+c[i]) (k > 0, i >= a[l] , j >= b[l], k= 1,2,3,4....n)
a[l]表示第l种用现金要的的钱数,b[l]表示第l种用积分兑换需要花的积分数。
#include<iostream> using namespace std; int dp[101][101][6]; //dp[l][i][j][k],表示选l件商品花费i元,j积分,p免费是获得的最大价值,滚动数组减一维 int a[101],b[101],c[101]; int n,v1,v2,k; #define max(a,b) ((a)>(b)?(a):(b)) int sovle() { int i,j,kk,l,ans; memset(dp,0,sizeof(dp)); for(i=0;i<n;i++) for(j=v1;j>=0;j--) for(kk=v2;kk>=0;kk--) for(l=k;l>=0;l--) { ans=0; if(j>=a[i]) ans=max(ans,dp[j-a[i]][kk][l]+c[i]); if(kk>=b[i]) ans=max(ans,dp[j][kk-b[i]][l]+c[i]); if(l>=1) ans=max(ans,dp[j][kk][l-1]+c[i]); dp[j][kk][l]=max(ans,dp[j][kk][l]); } return dp[v1][v2][k]; } int main() { int i; while(cin>>n>>v1>>v2>>k) { for(i=0;i<n;i++) cin>>a[i]>>b[i]>>c[i]; cout<<sovle()<<endl; } return 0; }
时间: 2024-09-30 09:50:13