牛客OI周赛15-普及组 B三角形

链接:https://ac.nowcoder.com/acm/problem/204553
来源:牛客网

宝盒

题目描述

上天眷顾了牛牛,给牛牛n个宝盒。牛牛会从这n个箱子中各取一件宝物去当掉来换钱(每个箱子中有m 件宝物)。牛牛想知道他用不同的方法取宝物能当来的钱数量的前k小值,为了避免输出量过大只要输出前k小的累计和。

输入描述:

第一行一个整数n,k,表示宝箱个数以及前k小的可获得的价值,接下来n行每行开头一个整数mi 表示第一个宝箱中宝物个数,接下来mi个数表示每件宝物的价值wi

输出描述:

一行一个整数ans,前k小和。

示例1

输入
3 10
4 1 3 4 5
3 1 7 9
4 1 2 3 5
输出
57

说明

前10小分别为{3,4,5,5,6,6,7,7,7,7}3,4,5,5,6,6,7,7,7,7

//动态规划就可以了
//package 牛客赛;
import java.util.*;
public class Main {
	public static int a[][]=new int [105][105*105];
	public static int dp[][]=new int [105][105*105];//dp[i][j]表示前i组组成和为j的个数
    public static int len[]=new int [105];
	public static void main(String[] args) {
		Scanner sc =new Scanner(System.in);
		int n=sc.nextInt();
		int k=sc.nextInt();
		for(int i=1;i<=n;i++)
		{
			 len[i]=sc.nextInt();
			for(int j=1;j<=len[i];j++)
				a[i][j]=sc.nextInt();
		}
		for(int i=1;i<=len[1];i++) dp[1][a[1][i]]=1;
		
		for(int i=2;i<=n;i++)
		{
			for(int j=1;j<=len[i];j++)
			{
				for(int p=1;p<=10000;p++)
				{
					if(p+a[i][j]<=10000)
					dp[i][p+a[i][j]]+=(dp[i-1][p]);
				}
			}
		}
		long ans=0;
		for(int i=1;i<=10000;i++)//判断前k个
		{
			if(dp[n][i]!=0)
			{
				if(k-dp[n][i]>=0) {
					ans+=(dp[n][i]*i);
				    k=k-dp[n][i];
				}
				else {
					ans+=k*i;
					k=0;
				}
			}
			if(k==0)
				break;
		}
		System.out.println(ans);
	}
}


发布了23 篇原创文章 · 获赞 0 · 访问量 368

猜你喜欢

转载自blog.csdn.net/qq_43328587/article/details/105356560