CodeForces - 1560F2 Nearest Beautiful Number (hard version)(二分+数位dp)
生活随笔
收集整理的這篇文章主要介紹了
CodeForces - 1560F2 Nearest Beautiful Number (hard version)(二分+数位dp)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題目鏈接:點擊查看
題目大意:給出一個十進制數字 nnn 和一個約束 kkk,問大于等于 nnn 且滿足不同的數位個數小于等于 kkk 的最小的數字是多少
題目分析:自己寫的貪心太丑了,就不放上來丟人了
偷的楊大佬的trick,對于某個數字 xxx,如果可以快速求出區間 [1,x][1,x][1,x] 中有多少個數字滿足不同的數位個數小于等于 kkk 的話,顯然這個答案是具有單調性的
考慮二分答案,然后用數位dp快速求解這個過程,dp[pos][state][k]dp[pos][state][k]dp[pos][state][k] 記憶化一下到了第 pospospos 位置,當前不同的數位狀態為 statestatestate,小于等于 kkk 的方案數。這里的 statestatestate 是一個 [0,210][0,2^{10}][0,210] 的數,也就是狀壓了一下狀態
雖然時間復雜度看起來很不可觀,但是據楊大佬的經驗所述,均攤下來的時間復雜度為 O(很快)O(很快)O(很快)
代碼:
// Problem: F2. Nearest Beautiful Number (hard version) // Contest: Codeforces - Codeforces Round #739 (Div. 3) // URL: https://codeforces.com/contest/1560/problem/F2 // Memory Limit: 256 MB // Time Limit: 1000 ms // // Powered by CP Editor (https://cpeditor.org)// #pragma GCC optimize(2) // #pragma GCC optimize("Ofast","inline","-ffast-math") // #pragma GCC target("avx,sse2,sse3,sse4,mmx") #include<iostream> #include<cstdio> #include<string> #include<ctime> #include<cmath> #include<cstring> #include<algorithm> #include<stack> #include<climits> #include<queue> #include<map> #include<set> #include<sstream> #include<cassert> #include<bitset> #include<list> #include<unordered_map> #define lowbit(x) (x&-x) using namespace std; typedef long long LL; typedef unsigned long long ull; template<typename T> inline void read(T &x) {T f=1;x=0;char ch=getchar();while(0==isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}while(0!=isdigit(ch)) x=(x<<1)+(x<<3)+ch-'0',ch=getchar();x*=f; } template<typename T> inline void write(T x) {if(x<0){x=~(x-1);putchar('-');}if(x>9)write(x/10);putchar(x%10+'0'); } const int inf=0x3f3f3f3f; const int N=1e6+100; int dp[15][(1<<10)+10][10]; int b[15],cnt,k; inline int count(int x) {return __builtin_popcount(x); } int dfs(int pos,int state,int limit,int lead) {if(pos==-1) {return count(state)<=k;}if(dp[pos][state][k]!=-1&&!limit&&!lead) {return dp[pos][state][k];}int up=limit?b[pos]:9;int ans=0;for(int i=0;i<=up;i++) {if(lead&&i==0) {ans+=dfs(pos-1,state,limit&&i==up,1);} else {ans+=dfs(pos-1,state|(1<<i),limit&&i==up,0);}}if(!limit&&!lead) {dp[pos][state][k]=ans;}return ans; } int solve(LL x) {cnt=0;while(x) {b[cnt++]=x%10;x/=10;}return dfs(cnt-1,0,1,1); } int main() { #ifndef ONLINE_JUDGE // freopen("data.in.txt","r",stdin); // freopen("data.out.txt","w",stdout); #endif // ios::sync_with_stdio(false);memset(dp,-1,sizeof(dp));int w;cin>>w;while(w--) {int n;read(n),read(k);int cur=solve(n-1);LL l=n,r=2e9,ans=-1;while(l<=r) {LL mid=(l+r)>>1;if(solve(mid)-cur>=1) {ans=mid;r=mid-1;} else {l=mid+1;}}printf("%lld\n",ans);}return 0; }總結
以上是生活随笔為你收集整理的CodeForces - 1560F2 Nearest Beautiful Number (hard version)(二分+数位dp)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 2021牛客多校9 - Cells(推公
- 下一篇: 2020ICPC沈阳 - United