【学习笔记】CF1225G To Make 1

不难观察到 ∑ a i k − b i = 1 \sum a_ik^{-b_i}=1 aikbi=1,将其看成 k k k进制小数,从低到高位考虑,每一位进位后恰好为 0 0 0。那么我们将数字逐次加入,从低位到高位进位的过程恰好就是合并的顺序。

考虑暴力 d p dp dp。设 d p S , i dp_{S,i} dpS,i表示使用了 S S S中的数字,考虑到第 i i i位时当前数位上合法的值的表。注意到转移是平移操作可以 bitset \text{bitset} bitset优化。

复杂度 O ( 2 n n 2 M w ) O(2^nn^2\frac{M}{w}) O(2nn2wM)。注意到位数可以省掉,可以优化一个 n n n

#include<bits/stdc++.h> #define fi first #define se second #define ll long long #define pb push_back #define inf 0x3f3f3f3f using namespace std; int n,K,a[20]; bitset<2005>dp[1<<16]; vector<int>vi[101],v; signed main(){ ios::sync_with_stdio(false); cin.tie(0),cout.tie(0); cin>>n>>K;for(int i=0;i<n;i++)cin>>a[i]; dp[0][0]=1; for(int i=0;i<1<<n;i++){ v.clear(); for(int j=dp[i]._Find_first();j<=2000;j=dp[i]._Find_next(j))v.pb(j); for(auto x:v){ while(x&&x%K==0)dp[i][x/=K]=1; } for(int j=0;j<n;j++){ if(!(i>>j&1)){ dp[i|(1<<j)]|=(dp[i]<<a[j]); } } }if(dp[(1<<n)-1][1]){ cout<<"YES"<<"\n";int S=(1<<n)-1,sum=1; for(int j=100;j>=0;j--){ sum*=K;assert(dp[S][sum]); for(int k=0;k<n;k++){ if((S>>k&1)&&sum>=a[k]&&dp[S^(1<<k)][sum-a[k]]){ S^=(1<<k),sum-=a[k],vi[j].pb(a[k]); } }if(!S)break; }assert(S==0);vector<int>v,v2; for(int j=0;j<=100;j++){ for(auto x:vi[j])v.pb(x); int X=0;v2.clear(); for(auto x:v){ if(x%K==0)v2.pb(x/K); else if(!X)X=x; else { cout<<X<<' '<<x<<"\n"; X+=x;if(X%K==0)v2.pb(X/K),X=0; } }v=v2; } }else{ cout<<"NO"; } }

__EOF__

本文作者仰望星空的蚂蚁
本文链接https://www.cnblogs.com/cqbzly/p/17530047.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   仰望星空的蚂蚁  阅读(10)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· DeepSeek 开源周回顾「GitHub 热点速览」
点击右上角即可分享
微信分享提示