#dp,Dilworth定理#洛谷 4934 礼物

题目传送门


分析

首先,可以放在一起当且仅当 max{ai,aj}&min{ai,aj}min{ai,aj}

根据 Dilworth 定理可知最小链划分中链的数目等于最长反链的长度

所以设 dp[i] 表示以 i 为结尾的反链的最大长度,则 dp[i]=maxj|i{dp[j]}+[ak==i]

构造可以根据当前的 dp 值划分给各个箱子,因为最终答案为 dp[2k1]


代码

#include <cstdio>
#include <cctype>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
const int N=1050011;
int n,m,v[N],dp[N];
vector<int>K[N];
int iut(){
	int ans=0,f=1; char c=getchar();
	while (!isdigit(c)) f=(c=='-')?-f:f,c=getchar();
	while (isdigit(c)) ans=ans*10+c-48,c=getchar();
	return ans*f; 
}
void print(int ans){
	if (ans>9) print(ans/10);
	putchar(ans%10+48);
}
int main(){
	n=iut(),m=iut();
	for (int i=1;i<=n;++i) ++v[iut()];
	for (int i=0;i<(1<<m);++i){
		for (int j=i;j;j&=j-1) dp[i]=max(dp[i],dp[i^(-j&j)]);
		if (v[i]) K[++dp[i]].push_back(i);
	}
	putchar(49),putchar(10),print(dp[(1<<m)-1]);
	for (int i=1,len;i<=dp[(1<<m)-1];++i){
		putchar(10),print(len=K[i].size());
		for (int j=0;j<len;++j) putchar(32),print(K[i][j]);
	}
	return 0;
}
posted @   lemondinosaur  阅读(9)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 张高兴的大模型开发实战:(一)使用 Selenium 进行网页爬虫
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
点击右上角即可分享
微信分享提示