宁波工程学院2020新生校赛J - 小梁的背包(01背包)

链接:https://ac.nowcoder.com/acm/contest/6106/J
来源:牛客网

时间限制:C/C++ 2秒,其他语言4秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld

题目描述

小梁来到了伽勒尔地区并参加了联盟赛热身赛,比赛小岛上有n个精灵散落在岛上各处,她有一个大小为s的背包,每个精灵的战斗值为v,体积为w
请问在她临走之前背包内宝可梦的战斗力总和最多为多少,并输出其战斗值总和sum以及背包内的精灵数量ans。

输入描述:

输入一个整数T(1≤T≤200)表示测试组数
每组数据的第一行有两个整数 n,s(1≤n,s≤104 )
接下来有n行数据,每行两个代表宝可梦体积w和战斗值v (1≤w,v≤104 )

输出描述:

输出T组,每组一行sum 和 ans
示例1
输入
1
5 5
1 3
2 5
1 2
4 2
6 1
输出
10 3

题目大意:

给出一个体积为s的背包,然后给出n个精灵的战斗力和体积,求背包内的精灵战斗力总和最大是多少,并输出背包内有几只精灵。

解题思路:

01背包模板题,但是这道题是1e4的,显然二维dp会超内存,优化一下优化到一维,用结构体存数据,dp[v].val表示体积小于v的情况下,战斗力最大是多少,dp[v].ans表示当前状态下有多少个精灵。
状态转移方程:
dp[i].val=dp[j-v[i]].val+w[i]
dp[i].ans=dp[j-v[i]].ans+1

AC代码:

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
const int _max=1e4+50;
int w[_max],v[_max];
struct node { int val,ans; };
node dp[_max];
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        memset(dp,0,sizeof dp);
        int n,m;
        cin>>n>>m;
        for(int i=1;i<=n;i++)
          cin>>v[i]>>w[i];
        for(int i=1;i<=n;i++)
          for(int j=m;j>=v[i];j--)//01背包原地滚动从后往前枚举
          {
            if(dp[j].val<dp[j-v[i]].val+w[i])
            {
                dp[j].val=dp[j-v[i]].val+w[i];
                dp[j].ans=dp[j-v[i]].ans+1;
            }
          }
        cout<<dp[m].val<<" "<<dp[m].ans<<endl;
    }
    //system("pause");
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值