Problem A number

使用一个$2^k$数集中每个元素的和表示数$n$,不同集合的数目有多少?

对于$100\%$的数据满足$1 \leq n \leq 10^6$

  Solution :

  $f[i][j]$表示使用不大于$2^i$的数组成集合,构成数$j$的不同集合数目。

  利用完全背包的思想,一开始$f[i+1][j] = f[i][j] + \sum_{k} f[i][j-k * 2^{i+1}]$

  显然可以通过滚动数组来优化,利用完全背包的思想,我们得到如下算法:

  一开始令$f[i+1][j] = f[i][j]$,然后从小到大考虑每一个$j$,用$f[i+1][j] += f[i+1][j-2^{i+1}]$的dp方程转移。

  时间复杂度$O(n log_2 n)$

# include<bits/stdc++.h>
# define int long long
# define MOD(x) ((x>=mo)?(x-mo):(x))
using namespace std;
const int N=1e6+;
const int mo=;
int n,f[N];
signed main() {
scanf("%lld",&n); f[]=;
for (int i=;(<<i)<=n;i++)
for (int j=;j<=n;j++)
if (j>=(<<i)) f[j]=MOD(f[j]+f[j-(<<i)]);
printf("%lld\n",f[n]%mo);
return ;
}

number.cpp

Problem B game

  有$n$个变量$x_1,x_2,...,x_n$,并给出$d$, 现在有$m$个限制$(a,b)$,满足$|x_a - x_b| \leq d$

  求出$max\{x_1,x_2,...,x_n\} - min\{x_1,x_2,...,x_n\}$的最大值,且满足上述限制。

  对于$100\%$的数据满足$n\leq 500$

  Solution :

    首先答案一定是$d$的倍数,所以我们只需要将每一条边权变为$1$,来考虑这个问题。

    将每一条限制建图,我们不妨考虑从点$i$开始到点$i$结束的一个环。

    显然,要让这个环上的点都满足条件,其权值最大的点必然是这个环的中点。

    这个中点的权值,等价于从$i$为源点,到所有目标点$j$最短路的最大值。

    考虑不在这个环上的所有边,必然可以构造出一种合法状态使整个图满足条件。

    所以,本题的答案和求出这个图中最短路的最大值等价。

    直接用$floyd$即可,时间复杂度为$O(n^3)$

#include<bits/stdc++.h>
using namespace std;
int n;
int f[][];
int d;
int solve(){
cin >> n; cin >> d;
for (int i=;i<=n;i++){
for (int j=;j<=n;j++){
char c;
cin >> c;
if (c == 'N') f[i][j] = 0x3f3f3f3f;
else f[i][j] = ;
if (i == j) f[i][j] = ;
}
}
for (int k=;k<=n;k++)
for (int i=;i<=n;i++)
for (int j=;j<=n;j++)
f[i][j] = min(f[i][j], f[i][k] + f[k][j]); int ans = ;
for (int i=;i<=n;i++){
for (int j=;j<=n;j++)
ans = max(ans, f[i][j]);
}
if (ans > ) cout << - << endl;
else cout << (long long)ans * d << endl;
} int main(){
// freopen("bridge.in","r",stdin);
// freopen("bridge.out","w",stdout);
int T;
cin >> T;
while (T--){
solve();
}
}

game.cpp

Problem C queue

  有一个$[1,n]$的排列,每一次可以将一个数移到排列的头部或者尾部。

   求出最小操作次数使得排列有序。

   对于$100\%$的数据满足$1 \leq n\leq 10^5$

  Solution :

    本题有一个加强版$CF1223D$. (可以把那个代码粘贴过来,然后就A掉了)

    还是重新考虑这个弱化版本,甚至还不需要用离散化。

    一个答案的构造一定满足$l,l-1,l-2,...,1$依次放到队首,$r,r+1,...,n$依次放到队尾。

    于是我们可以$dp$,设$dp[i]$表示$i$之前的最长的长度,使得$i - dp[i]+1, i-dp[i] , ... i$这些数有序。

    那么最后的答案必然是$n - max(dp[i])$

    对于本题,等价于求出n - 连续最长上升子序列,时间复杂度为$O(n)$

# include <bits/stdc++.h>
using namespace std;
const int N=3e5+;
int n,a[N],dp[N],MinID[N],MaxID[N];
vector<int>tmp;
inline int read()
{
int X=,w=; char c=;
while(c<''||c>'') {w|=c=='-';c=getchar();}
while(c>=''&&c<='') X=(X<<)+(X<<)+(c^),c=getchar();
return w?-X:X;
}
int main()
{
int T=;
while (T--) {
tmp.clear();
n=read();
for (int i=;i<=n;i++) {
a[i]=read();
tmp.push_back(a[i]);
}
sort(tmp.begin(),tmp.end());
tmp.erase(unique(tmp.begin(),tmp.end()),tmp.end());
for (int i=;i<=n;i++) {
a[i] = lower_bound(tmp.begin(),tmp.end(),a[i]) - tmp.begin() + ;
}
int sz = tmp.size();
for (int i=;i<=sz;i++) MinID[i]=0x3f3f3f3f,MaxID[i]=-0x3f3f3f3f;
for (int i=;i<=n;i++) {
MinID[a[i]] = min(MinID[a[i]],i);
MaxID[a[i]] = max(MaxID[a[i]],i);
}
dp[]=; int ans = sz-;
for (int i=;i<=sz;i++) {
if (MaxID[i-] < MinID[i]) dp[i]=dp[i-]+;
else dp[i]=;
ans = min(ans,sz-dp[i]);
}
printf("%d\n",ans);
}
return ;
}

CF1223D

# include<bits/stdc++.h>
using namespace std;
const int N=1e5+;
int n,p[N],a[N],f[N],ans;
int main()
{
scanf("%d",&n);
for (int i=;i<=n;i++) scanf("%d",&a[i]),p[a[i]]=i;
for (int i=;i<=n;i++) {
f[i]=;
if (p[a[i]-]<i) f[i] = max(f[i],f[p[a[i]-]]+);
ans = max(ans,f[i]);
}
printf("%d\n",n-ans);
return ;
}

queue.cpp

HGOI 20191103am 题解的更多相关文章

  1. HGOI 20181028 题解

    HGOI 20181028(复赛备考) /* 真是暴力的一天,最后一题MLE?由于数组开得太大了!!! 270滚粗 考场上好像智商高了很多?!(假的) */ sol:暴力求解,然后没有数据范围吐槽一下 ...

  2. HGOI 20190310 题解

    /* 又是又双叒叕WA的一天... 我太弱鸡了... 今天上午打了4道CF */ Problem 1 meaning 给出q组询问,求下列函数的值$ f(a) = \max\limits_{0 < ...

  3. HGOI 20190303 题解

    /* 记一串数字真难. 5435 今天比赛又是hjcAK的一天. 今天开题顺序是312,在搞T1之前搞了T3 昨天某谷月赛真是毒瘤. 但是讲评的同学不错,起码T4看懂了... 构造最优状态然后DP的思 ...

  4. HGOI 20180224 题解

    /* The Most Important Things: ljc chat with fyh on QQTa说期末考Ta数学74分感觉不好但是我觉得fyh是地表最强的鸭~~(of course en ...

  5. HGOI 20190218 题解

    /* 又是AK局... hjc又双叒叕AK了... Hmmm...我侥幸 */ Problem A card 给出无序序列a[]可以选择一个数插入到合适的位置作为一次操作,至少多少次操作后可以把序列变 ...

  6. HGOI 20190217 题解

    /* for me,开训第一天 /beacuse 文化课太差被抓去补文化课了... 看一眼题 : AK局? 但是,Wa on test #10 in problem C 290! (就差那么一咪咪) ...

  7. HGOI 20181103 题解

    problem:把一个可重集分成两个互异的不为空集合,两个集合里面的数相乘的gcd为1(将集合中所有元素的质因数没有交集) solution:显然本题并不是那么容易啊!考场上想了好久.. 其实转化为上 ...

  8. HGOI 20181101题解

    /* 又是爆0的一天(不知道今年高考难不难,反正今天(信息学)真的难!) */ solution:对于两个数相加,有一个显然的结论就是要么不进位(相对于位数大的),要么(进最多一位) 然后对于整个数组 ...

  9. HGOI 20191108 题解

    Problem A 新婚快乐 一条路,被$n$个红绿灯划分成$n+1$段,从前到后一次给出每一段的长度$l_i$,每走$1$的长度需要$1$分钟. 一开始所有红绿灯都是绿色的,$g$分钟后所有红绿灯变 ...

随机推荐

  1. Linux挂载磁盘&kuoron

    1.添加磁盘 物理服务器直接插上硬盘即可,虚拟机的话给直接添加磁盘即可,不懂的可以自行百度,比较简单. 2.管理磁盘分区,fdisk命令. 在Linux系统中,管理硬盘设备最常用的方法就当属 fdis ...

  2. Python基础 第三章 使用字符串(1)精简版

    所有标准序列操作(索引,切片,乘法,成员资格检查,长度,最小值,最大值)都适于字符串. 但,字符串是不可变得,故所有得元素赋值和切片赋值都是非法的. 1. %s 转换说明符 设置字符串格式 %左边指定 ...

  3. python中sort和sorted用法的区别

    Python list内置sort()方法用来排序,也可以用python内置的全局sorted()方法来对可迭代的序列排序生成新的序列 一,最简单的排序 1.使用sort排序 my_list = [3 ...

  4. 1、windows安装npm教程 --参考自https://www.cnblogs.com/jianguo221/p/11487532.html

    windows安装npm教程   1.在使用之前,先类掌握3个东西,明白它们是用来干什么的: npm:  nodejs 下的包管理器. webpack: 它主要用途是通过CommonJS 的语法把所有 ...

  5. Lua虚拟机中的数据结构与栈

    Lua虚拟机中的数据结构与栈 来源 https://blog.csdn.net/zry112233/article/details/80828327 由上一篇文章可知解释器分析Lua文件之后生成Pro ...

  6. VM安装vmtools后centos7无法上网

    先安装VmTools工具 文件 /etc/sysconfig/network-scripts/ifcfg-ens33(这里的enp0s3不是固定的,看你具体情况,但是基本是en开头的) 将 ONBOO ...

  7. CentOS下安装好python和opencv,却import cv2失败

    在安装好CentOS和OpenCV后,在终端输入python,在输入import cv2.却报错:ImportError:Mo module named cv2.浏览Python下文件夹发现cv2.s ...

  8. 2019牛客暑期多校训练营(第一场)E ABBA

    题意问你有多少个长度为2*(n+m)的字符串满足A和B数量相等 且可以分割为n个AB子序列和m个BA子序列 很容易得出前n个A肯定是可以给AB的 后面的m个A给BA 所以当一个字符串满足条件时要满足任 ...

  9. OpenJudge POJ C19C 贪心

    https://cn.vjudge.net/contest/309482#problem/C #include<bits/stdc++.h> using namespace std; ty ...

  10. P2057 善意的投票 最小割理解

    实现时这样建图:直接将S连向同意的人,T连向不同意的人,若两人是朋友,则在他们之间连一条双向边 #include<bits/stdc++.h> #define il inline usin ...