牛客OI周赛15-普及组

比赛链接

牛客OI周赛15-普及组

B.三角形

题目描述

上天眷顾了牛牛,给牛牛 \(\mathrm{n}\) 个宝盒。牛牛会从这 \(\mathrm{n}\) 个箱子中各取一件宝物去当掉来换钱(每个箱子中有 \(m_{i}\) 件宝物) 。 牛牛想知道他用不同的方法取宝物能当来的钱数量的前k小值,为了避免输出量过大只要输出 \(\sum a_{i}(i \leq k)\) 即可,其 中的 \(a_{i}\) 为第i/值。

输入描述:

第一行一个整数 \(n, k\), 表示宝箱个数以及前 \(\mathrm{k}\) 小的可获得的价值
接下来n行每行开头一个整数 \(m_{i}\) 表示第一个宝箱中宝物个数, 接下来 \(m_{i}\) 个数表示每件宝物的价值 \(w_{i}\)

输出描述:

一行一个整数 \(a n s\), 表示 \(\sum a_{i}(i \leq k)\)

输入

3 10
4 1 3 4 5
3 1 7 9
4 1 2 3 5

输出

57

备注:

对于 \(50 \%\) 的数据: \(n, m_{i} \leq 10\)
对于 \(100 \%\) 的数据: \(n, m_{i} \leq 100, k \leq 10000\), 保证每个宝物的价值为不超过 \(100\) 的正整数, 所有 \(m_{i}\) 的积大 于等于 \(k\)

解题思路

分组背包

  • 状态表示:\(f[i][j]\) 表示前 \(i\) 个物品,价值和为 \(j\) 的方案数

  • 状态计算:\(f[i][j]+=f[i-1][j-a[i][k]]\)

然后按价值从小到大选出 \(k\) 个方案来即可

  • 时间复杂度:\(O(10000n\sum m)\)

代码

// Problem: 三角形
// Contest: NowCoder
// URL: https://ac.nowcoder.com/acm/contest/32343/B
// Memory Limit: 1048576 MB
// Time Limit: 2000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

// %%%Skyqwq
#include <bits/stdc++.h>
 
//#define int long long
#define help {cin.tie(NULL); cout.tie(NULL);}
#define pb push_back
#define fi first
#define se second
#define mkp make_pair
using namespace std;
 
typedef long long LL;
typedef pair<int, int> PII;
typedef pair<LL, LL> PLL;
 
template <typename T> bool chkMax(T &x, T y) { return (y > x) ? x = y, 1 : 0; }
template <typename T> bool chkMin(T &x, T y) { return (y < x) ? x = y, 1 : 0; }
 
template <typename T> void inline read(T &x) {
    int f = 1; x = 0; char s = getchar();
    while (s < '0' || s > '9') { if (s == '-') f = -1; s = getchar(); }
    while (s <= '9' && s >= '0') x = x * 10 + (s ^ 48), s = getchar();
    x *= f;
}

const int N=105;
int n,k,f[N][10005],a[N],s;
int main()
{
    cin>>n>>k;
    f[0][0]=1;
    for(int i=1;i<=n;i++)
    {
    	cin>>s;
    	for(int k=1;k<=s;k++)cin>>a[k];
    	for(int k=1;k<=10000;k++)
	    	for(int j=1;j<=s;j++)
	    		if(a[j]<=k)f[i][k]+=f[i-1][k-a[j]];
    }
    int res=0;
    for(int i=1;i<=10000;i++)
    	if(f[n][i]&&k>0)
    	{
    		res+=i*min(k,f[n][i]);
    		k-=f[n][i];
    	}
    cout<<res;
    return 0;
}
posted @ 2022-04-08 18:11  zyy2001  阅读(19)  评论(0编辑  收藏  举报