您的位置:首页 > 其它

HDU 5410 CRB and His Birthday (2015年多校比赛第10场)

2015-08-21 11:12 267 查看
1.题目描述:点击打开链接

2.解题思路:本题是完全背包问题的一种变形。根据题意描述,每种物品的价值随着A[i]是线性变化的,但是并不随着B[i]线性变化,B[i]仅仅是在第一次挑选第i件物品是才算入,其他时候均不算入。因此,这里的状态要比普通的完全背包增加一个维度:是否是第一次选第i件物品,即用(i,j,flag)表示当前背包容量为j时,是否为第一次选第i件物品时的最大价值。那么不难得到如下状态转移方程:

dp(i+1,j,0)=max{dp(i,j,0),dp(i,j,1)};

dp(i+1,j,1)=max{dp(i+1,j-w[i],0)+A[i]+B[i],dp(i+1,j-w[i],1)+A[i]}; (j≥w[i])

第一个方程表示不选第i件物品时,它的最大值来源于买前i件物品时候的最大值。第二个方程表示选第i件物品时,如果第i件物品时第一次被选择,那么等于dp(i+1,j-w[i],0)+A[i]+B[i],如果他已经被选过了,那么等于dp(i+1,j-w[i],1)+A[i]。取两个的较大者即可。

3.代码:

//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<iostream>
#include<algorithm>
#include<cassert>
#include<string>
#include<sstream>
#include<set>
#include<bitset>
#include<vector>
#include<stack>
#include<map>
#include<queue>
#include<deque>
#include<cstdlib>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<ctime>
#include<cctype>
#include<functional>
using namespace std;

#define me(s)  memset(s,0,sizeof(s))
#define rep(i,n) for(int i=0;i<(n);i++)
typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;
typedef pair <int, int> P;

const int N=2000+10;

int dp

[2];
int A
,B
;
int w
;

int main()
{
    int T;
    for(scanf("%d",&T);T--;)
    {
        int M,n;
        scanf("%d%d",&M,&n);
        for(int i=0;i<n;i++)
            scanf("%d%d%d",&w[i],&A[i],&B[i]);
        me(dp);
       for(int i=0;i<n;i++)
        for(int j=0;j<=M;j++)
       {
           dp[i+1][j][0]=max(dp[i][j][0],dp[i][j][1]);
           if(j>=w[i])
           dp[i+1][j][1]=max(dp[i+1][j-w[i]][0]+A[i]+B[i],dp[i+1][j-w[i]][1]+A[i]);
       }
       int ans=max(dp
[M][0],dp
[M][1]);
       printf("%d\n",ans);
    }
}


同样的,这个方程可以去掉i的维度,变成一个二维数组。
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<iostream>
#include<algorithm>
#include<cassert>
#include<string>
#include<sstream>
#include<set>
#include<bitset>
#include<vector>
#include<stack>
#include<map>
#include<queue>
#include<deque>
#include<cstdlib>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<ctime>
#include<cctype>
#include<functional>
using namespace std;

#define me(s)  memset(s,0,sizeof(s))
#define rep(i,n) for(int i=0;i<(n);i++)
typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;
typedef pair <int, int> P;

const int N=2000+10;

int dp
[2];
int A
,B
;
int w
;

int main()
{
    int T;
    for(scanf("%d",&T);T--;)
    {
        int M,n;
        scanf("%d%d",&M,&n);
        for(int i=0;i<n;i++)
            scanf("%d%d%d",&w[i],&A[i],&B[i]);
        me(dp);
        for(int i=0;i<n;i++)
            for(int j=0;j<=M;j++)
            {
                dp[j][0]=max(dp[j][0],dp[j][1]);
                if(j>=w[i])
                dp[j][1]=max(dp[j-w[i]][0]+A[i]+B[i],dp[j-w[i]][1]+A[i]);
            }
        int ans=max(dp[M][0],dp[M][1]);
        printf("%d\n",ans);
    }
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: