ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Codeforces1699E Three Days Grace【数学】【DP】

2022-08-16 14:31:16  阅读:249  来源: 互联网

标签:pq int Three pop Days while del now Codeforces1699E


分析:

一开始觉得是二分答案,发现行不通之后改为枚举最小值。

现在我将这若干个数分解,假设分解完之后得到的最小值为$i$,那么我就是要在最小值为$i$的基础上尽量最小化分解的各数的最大值。

考虑DP:设$f[x][i]$表示在分解结果最小值大于等于$i$的情况下,将$x$分解得到的最大值最小是多少。可以得到如下转移:

$$f[x][i] = min(f[\frac{x}{i}][i],f[x][i+1])\quad where\ i\ is\ a\ factor\ of\ x$$

或者

$$f[x][i] = f[x][i+1]\quad i\ is\ not\ x's\ factor$$

注意到这样转移状态数太多了,但是我们发现,只有当$i$是$x$的因子时,$f[x][i]$的值才会发生变化,所以转移可以进一步优化,只留$n\ln n$个有用的状态。

接着,答案就是对每个枚举的$i$,求$f[a[x]][i]$的最大值即可。

这个求最大值的过程如果倒着用可删堆维护会爆空间,所以考虑正着来。先倒着预处理出来$i$等于多少时,$f[x][i]$会发生变化就行了。(参考我代码里的update部分)

代码:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 
 4 const int maxn = 1050000;
 5 const int maxm = 5050000;
 6 
 7 int n,m;
 8 int a[maxn];
 9 int suf[maxm];
10 int tab[maxm];
11 int update[maxm];
12 
13 struct Priority_Queue{
14     priority_queue<int,vector<int>,less<int> > pq,del;
15     void Push(int now){pq.push(now);}
16     void Del(int now){del.push(now);}
17     int Top(){
18     while(!del.empty() && pq.top() == del.top()){
19         pq.pop();
20         del.pop();
21     }
22     return pq.top();
23     }
24     void clear(){
25     while(!pq.empty()) pq.pop();
26     while(!del.empty()) del.pop();
27     }
28 }Q;
29 
30 int main(){
31     int t; scanf("%d",&t);
32     while(t--){
33     scanf("%d%d",&n,&m);
34     int minn = 1e9,maxx = 0;
35     Q.clear();
36     for(int i=1;i<=n;i++) {
37         scanf("%d",&a[i]);
38         minn = min(minn,a[i]);
39         maxx = max(maxx,a[i]);
40     }
41     for(int i=1;i<=maxx;i++){
42         suf[i] = i;
43         tab[i] = 0;
44         update[i] = 0;
45     }
46     for(int i=1;i<=n;i++) tab[a[i]]=1;
47     int ans = 1e9;
48     for(int i=maxx;i>=2;i--){
49         for(int j=i;1ll*j*i<=maxx;j++){
50         if(tab[i*j]) update[i+1] = max(update[i+1],suf[i*j]);
51         suf[i*j] = min(suf[i*j],suf[j]);
52         }
53     }
54     for(int i=1;i<=maxx;i++){
55         if(tab[i]){
56         update[1] = max(update[1],suf[i]);
57         }
58     }
59     int tot = 0;
60     for(int i=1;i<=minn;i++){
61         tot = max(tot,update[i]);
62         ans = min(ans,tot-i);
63     }
64     printf("%d\n",ans);
65     }
66 }

 

标签:pq,int,Three,pop,Days,while,del,now,Codeforces1699E
来源: https://www.cnblogs.com/Menhera/p/16591450.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有