列表

详情


NC241415. 炼金术

描述

Background


「阿贝多哥哥又聪明又温柔,对可莉好极了!只要跟着阿贝多哥哥到处跑,可莉就能看到各种奇怪的东西,玩得超~开心!」 ——可莉

------------------------------------------------------------------------------------------------------------------------

无垢之土,创生原初之人。

在炼金术方上造诣极深,却不轻易说出事物的本质。

穿行在对真理一知半解的「凡人」间,示其以恰到好处的真诚与和善。

彬彬有礼,气质高雅。表面上疏于交际,其实并不吝于伸出援助之手。

如果认可你这位朋友,即便相识不久,他也会在百忙之中抽时间为你绘制精美的肖像画。

西风骑士团首席炼金术士阿贝多,正是这样一位神奇少年。从蒙德居民到骑士团成员,无不为他的学识所折服。

「天才」、「白垩之子」或「调查队长」······ 他不怎么在意称号和名望,只专注于研究课题。

财富和人脉不是他的目标。他渴望驾驭的,是从古到今深藏于人类头脑中的无上知识。

Description


阿贝多要进行一次炼金。

具体来说,阿贝多有 n 份原材料,均由 m 种元素中的某些构成。每份原材料有两个属性,其一为质量 w_i,其二为该原材料由哪些元素构成。

现在他需要选出其中的 k 份分别放入两个反应容器 ST 中,并且最大化 ST 的「活跃度」之积。

其中,S 的「活跃度」被定义为其中所有原材料的质量之和,T 的「活跃度」被定义为其中出现的元素种类数。

输入描述

第一行三个整数 n, k, m

接下来 n 行描述原材料信息,每行的第一个数为原材料质量 w_i,第二个数为构成该原材料的元素数量 q_i,接下来 q_i 个互不相同的正整数 描述构成该原材料的所有元素。

输出描述

一个数表示答案。

示例1

输入:

5 3 4
12 2 2 4
5 1 3
17 3 1 2 3
9 3 1 2 4
26 1 3

输出:

129

原站题解

import java.util.Scanner;
public class Main {
public static void main(String[] arg) {
Scanner scanner = new Scanner(System.in);
// todo
}
}
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

C++(g++ 7.5.0) 解法, 执行用时: 568ms, 内存消耗: 1472K, 提交时间: 2022-09-09 23:32:35

// Nothing is Given, Everything is Earned.
#include<bits/stdc++.h>
using namespace std;
#define X first
#define Y second
int main()
{
cin.tie(NULL)->sync_with_stdio(false);
int n,k,m; cin>>n>>k>>m;
vector<pair<int, int>> a(n);
for(int i=0,q;i<n;i++)
{
cin>>a[i].X>>q;
while(q--)
{
int c; cin>>c; c--;
a[i].Y|=1<<c;
}
}
sort(a.begin(),a.end());
vector<int> popcnt(1<<m);
for(int i=0;i<1<<m;i++) popcnt[i]=__builtin_popcount(i);
vector<int> suf(n+1),sum(n+1);
for(int i=n-1;~i;i--)
{
suf[i]=suf[i+1]|a[i].Y;
sum[i]=sum[i+1]+a[i].X;
}
vector f(m+1,vector(1<<m,-1));
for(int i=0;i<=min(m,k);i++) f[i][0]=0;
int ans=0;
for(int i=n-1;~i;i--)
{
vector g(m+1,vector(1<<m,-1));
for(int j=0;j<=m;j++)
{
for(int S=0;S<1<<m;S++) if(~f[j][S])
{
if(j) g[j-1][S|a[i].Y]=max(g[j-1][S|a[i].Y],f[j][S]);
g[j][S]=max(g[j][S],f[j][S]+(j+n-i-1<k?a[i].X:0));
}
}
swap(f,g);
for(int S=0;S<1<<m;S++) ans=max(ans,popcnt[S]*f[0][S]);
}
cout<<ans<<"\n";
return 0;
}

C++(clang++ 11.0.1) 解法, 执行用时: 997ms, 内存消耗: 2296K, 提交时间: 2022-09-10 11:21:09

#include<bits/stdc++.h>
using namespace std;
#define fr(i,a,b) for(int i=a;i<=b;i++)
#define ll long long
#define mod 998244353
#define N 1005
#define M 13
int n,m,K;
ll f[M+1][1<<M],g[M+1][1<<M],ans;
void chmx(ll& x,ll y){
if(x<y)x=y;
}
struct node{
int x,y;
friend bool operator< (node A,node B){
return A.x>B.x;
}
}a[N];
int main(){
scanf("%d%d%d",&n,&K,&m);
fr(i,1,n){
int len,z;
scanf("%d%d",&a[i].x,&len);
fr(j,1,len){
scanf("%d",&z);
a[i].y|=(1<<(z-1));
}
}
sort(a+1,a+n+1);
memset(f,-0x3f,sizeof f);
fr(i,0,m)f[i][0]=0;
fr(i,1,n){
int x=a[i].x,y=a[i].y;
memcpy(g,f,sizeof f);
fr(k,0,(1<<m)-1){
fr(j,0,m){
if(j)chmx(g[j-1][k|y],f[j][k]);
if(j+i<=K)chmx(g[j][k],f[j][k]+x);
}
}
memcpy(f,g,sizeof f);
}
fr(k,0,(1<<m)-1)if(f[0][k]>0)chmx(ans,f[0][k]*__builtin_popcount(k));
printf("%lld\n",ans);
return 0;
}

上一题