洛谷 P1064 金明的预算方案

       这是一个背包类型的问题,但是存在附件这个问题,因为要拿附件就一定要拿主件,而且附件最多只有2种,假设有2种附件,那么这个物品就有三种状态

        第一种就是只拿主键,dp[j] = max(dp[j], dp[j-now[i].v] + now[i].v*now[i].p);

        第二种就是那主键和第一个附件  dp[j] = max(dp[j], dp[j-now[i].v-vec[i][0].v] + now[i].v*now[i].p+vec[i][0].v*vec[i][0].p);

        第三种就是拿主键和第二个附件,基本同上。

       第四种就是拿主键和两个附件,dp[j] = max(dp[j], dp[j-now[i].v-vec[i][0].v-vec[i][1].v]+now[i].v*now[i].p+vec[i][1].v*vec[i][1].p+vec[i][0].v*vec[i][0].p);

        然后按照背包问题的转移方式做就可以了,滚动一下优化空间,代码如下。

#include <bits/stdc++.h>

using namespace std;

const int maxn = 1e2 + 10;

int dp[maxn*1000],v[maxn][4],val[maxn],q[maxn],a[maxn];

struct node {

    int q,v,p;

}now[maxn];

vector<node> vec[maxn];

int main(){

    int n,m;

    scanf("%d%d",&n,&m);

    for (int i=1; i<=m; i++) {

        cin >> now[i].v >> now[i].p >> now[i].q;

        if (now[i].q != 0) {

            vec[now[i].q].push_back(now[i]);

        }

    }

    for (int i=1; i<=m; i++) {

        if (now[i].q == 0) for (int j=n; j>=0; j--){

            if (j >= now[i].v)

                dp[j] = max(dp[j], dp[j-now[i].v] + now[i].v*now[i].p);

            if (vec[i].size() >= 1 && j >= now[i].v + vec[i][0].v)

                dp[j] = max(dp[j], dp[j-now[i].v-vec[i][0].v] + now[i].v*now[i].p+vec[i][0].v*vec[i][0].p);

            if (vec[i].size() >= 2 ){

                if (j >= now[i].v + vec[i][1].v)

                    dp[j] = max(dp[j], dp[j-now[i].v-vec[i][1].v]+now[i].v*now[i].p+vec[i][1].v*vec[i][1].p);

                if (j >= now[i].v + vec[i][0].v + vec[i][1].v)

                    dp[j] = max(dp[j], dp[j-now[i].v-vec[i][0].v-vec[i][1].v]+now[i].v*now[i].p+vec[i][1].v*vec[i][1].p+vec[i][0].v*vec[i][0].p);

            }

        }

    }

    cout << dp[n] << endl;

    return 0;

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值