- 博客(24)
- 收藏
- 关注
转载 差分约束
差分约束系统一、何为差分约束系统:差分约束系统(system of difference constraints),是求解关于一组变数的特殊不等式组之方法。如果一个系统由n个变量和m个约束条件组成,其中每个约束条件形如xj-xi<=bk(i,j∈[1,n],k∈[1,m]),则称其为差分约束系统(system of difference constraints)。亦即,差分约束系统是...
2018-08-13 21:20:53
193
原创 7.11evening
Solution 思路 因为要字典序最小,我们再举几个样例和感性认知后发现:若新序列P相对于原序列A第一个修改的数为Ai,则i要尽可能小。枚举i,那么如何判断i位作为第一个修改的数是否可行并构造可行解呢? 判断是否可行我们首先用树状数组 预处理出来p[i],表示第i位后有几个数字比它小,sum[i]表示i-n位的逆序对数目,显然sum[i]=sum[i+1]+p[i];若从i位开始修...
2018-07-12 08:12:16
203
原创 取火柴
做法:i).求出k=a1^a2^…^an,若k>0,则先取必胜,否则必败。ii).若k=0,把其中一个ai变成ai^k,但ai^k要小于ai证明:i).数学归纳法设当i=0…n时sg(i)=i成立1.当n=0时sg(0)=0,成立2.当i=n+1时,因为可以取小于n+1的任意多个火柴,所以后继状态是0..n,所以:sg(i)=mem(sg(0),sg(1),…...
2018-07-10 13:47:55
398
原创 末日解析
我们考虑把这个问题缩小范围。比如n=5,在决定了最小的数“1”的位置之后,剩下的几个数是2 3 4 5,但是他们具体是多少没必要关心,我们只要关心他们的相对大小关系。所以考虑完当前最小的数,算出这个数对答案的贡献,然后减掉这个贡献,就可以转而解决一个更小的子问题。(即n–>n-1)回到题目上,要求是求一个有m个逆序对的字典序最小的排列。我们知道一个长度为n的排列最多有...
2018-06-16 18:57:34
264
原创 分治总起
分治算法 一、基本概念在计算机科学中,分治法是一种很重要的算法。字面上的解释是“分而治之”,就是把一个复杂的问题分成两个或更多的相同或相似的子问题,再把子问题分成更小的子问题……直到最后子问题可以简单的直接求解,原问题的解即子问题的解的合并。这个技巧是很多高效算法的基础,如排序算法(快速排序,归并排序),傅立叶变换(快速傅立叶变换)……任何一个可以用计算机求解的问题所需的计算时间都与其规...
2018-02-08 07:20:58
202
转载 分治概念总起
分治算法 一、基本概念在计算机科学中,分治法是一种很重要的算法。字面上的解释是“分而治之”,就是把一个复杂的问题分成两个或更多的相同或相似的子问题,再把子问题分成更小的子问题……直到最后子问题可以简单的直接求解,原问题的解即子问题的解的合并。这个技巧是很多高效算法的基础,如排序算法(快速排序,归并排序),傅立叶变换(快速傅立叶变换)……任何一个可以用计算机求解的问题所需的计算时间都与其规...
2018-02-08 07:19:02
237
原创 来自一个懒人的分治讲解(1)
分治的基础思想是:大问题变成小问题,解决小问题后将答案合并为大问题的答案 分治法可以通俗的解释为:把一片领土分解,分解为若干块小部分,然后一块块地占领征服,被分解的可以是不同的政治派别或是其他什么,然后让他们彼此异化。 分治法的精髓: 分–将问题分解为规模更小的子问题; 治–将这些规模更小的子问题逐个击破; 合–将已解决的子问题合并,最终得出“母”问题的解;(1)数学方面的利用 举
2018-02-07 16:18:22
214
原创 洛谷p1280
#include<bits/stdc++.h>#define ll long long using namespace std;struct node{ ll s,e;}f[10005];ll n,k,dp[10005];ll vis[10005];bool cmp(node x,node y){ return x.s>y.s;}int main(){
2017-12-30 11:17:12
257
转载 汉诺塔
这里写代码片汉诺塔的递归实现算法,将A中的圆盘借助B圆盘完全移动到C圆盘上, 每次只能移动一个圆盘,并且每次移动时大盘不能放在小盘上面 递归函数的伪算法为如下: if(n==1) 直接将A柱子上的圆盘从A移动到C else 先将A柱子上的n-1个圆盘借助C柱子移动到B柱子上 直接将A柱子上的第n个圆盘移动到C柱子上 最后将B柱子上的n-1个圆盘借助A柱子移动到
2017-12-24 14:22:46
239
转载 波动序列
/ 只需要判断是递增或递减就行了,O(n)时间复杂度。 即:对于当前的点,1、如果要找递增序列:如果下一个点比当前的点大,序列长度加1,更新下一个点为当前点; 如果下一个点比当前点小,长度不变,同样更新下一个点为当前点,而且有利于找出递增序列 找递减序列的方法与找递增序列的方法一致。*/ #include<bits/s
2017-12-17 09:32:34
522
原创 最长不下降字序列
nlogn#include<cstdio>#include<algorithm>using namespace std;int a[40005];int d[40005];int main(){ int n; scanf("%d",&n); for (int i=1;i<=n;i++) scanf("%d",&a[i]); if (n==0) //0个元素特
2017-12-17 09:21:38
194
转载 洛谷p1023
#include<iostream>#include<cstdio>#include<algorithm>int x,x1,a[10001],b[10001],change,t=1,i,j,s,flag1,flag2,n1,n2,flag;int mscore(int a,int b){ return a>b;}using namespace std;int main(){
2017-12-17 08:19:11
455
原创 01背包
样板题 (日常打卡)#include<bits/stdc++.h>using namespace std;int a[10001],f[10001];int n,m;int main(){ scanf("%d%d",&n,&m); f[0]=1;//注意边界(被坑了一次) for(int i=1;i<=n;i++) { scanf("%d"
2017-12-17 08:18:39
131
转载 新数字三角形
将mod 100的值加入到状态中,变成判定性问题,这种情况下顺推比较方便。#include<iostream> #include<algorithm> using namespace std; bool f[100][100][100]; int a[100][100]; int main() { int n,ans=0; cin>>n;
2017-12-13 15:37:24
286
转载 城市交通网络
某dp题#include<iostream> #include<cstring> #define MAXN 100 using namespace std; int a[MAXN+5][MAXN+5];//a[i][x]表示vi到vx的最短距离 int f[MAXN+5];//f[i]表示点vi到v10的最短距离 int suf[MAXN+5];//suf[i]=x;表示
2017-12-12 14:57:33
736
原创 洛谷p2698花盆
滑动窗口的好题 从大到小算一次即可#include<iostream>#include<algorithm>#include<cmath>#include<cstdio>#include<bits/stdc++.h>using namespace std;int head=1,tail=1,j=2,minn=0X3f3f3f3f;int n,d;struct work{
2017-12-11 15:54:26
371
1
原创 洛谷p1542包裹快递
好久没写二分答案了 思路: 设定一个时间t; 在一段时间内如果行得通就把maxx减小搜 行不通就把最小值增大 如何判断 如果之前时间加上通过该路程距离时间大于最迟要求时间就跳过,小于最小就等,否则加上通过时间 具体看代码:#include<cstring>#include<string>#include<bits/stdc++.h>using namespace std;#de
2017-12-11 15:46:59
431
原创 洛谷p1091
dp经典题 *一遍递推算出最长上升子序列,再一遍递推算出最长下降子序列,再一遍历维护max求出答案。 建立二维数组a[105][2]。 a[i][0]代表以第i个人为结尾的最长上升子序列长度。(整个合唱队形没有下降) a[i][1]代表以第i个人为结尾的最长合唱队形,但至少有一个人的身高呈下降趋势(合唱队形有下降) 显然,max(a[i][0],a[i][1])代表前i个人的最长合唱队形。
2017-12-10 11:29:11
262
原创 洛谷p1804
一道dp题#include<bits/stdc++.h>using namespace std;const int x=1000007;int n,m,a[105],dp[105];int main(){ scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) { scanf("%d",&a[i]); }
2017-12-10 09:56:12
423
转载 string类函数总结(转载)
之所以抛弃char*的字符串而选用C++标准程序库中的string类,是因为他和前者比较起来,不必 担心内存是否足够、字符串长度等等,而且作为一个类出现,他集成的操作函数足以完成我们大多数情况下(甚至是100%)的需要。我们可以用 = 进行赋值操作,== 进行比较,+ 做串联(是不是很简单?)。我们尽可以把它看成是C++的基本数据类型。好了,进入正题……… 首先,为了在我们的程序中使用string
2017-12-09 18:37:26
182
原创 洛谷p1018
学到一个好东西 __int128 void print(__int128 x) { if(!x)return ; print(x/10); putchar(x%10+48); } (记得按位输出就好了高精都不用写了) 令f[i][j]表示前i个数放j个乘号得到的最大值 由于都是乘法,优先级一样,所以如果i之后还有乘号,可以之间调用这个f[i][j]进行运算
2017-12-09 18:34:41
632
原创 洛谷p2196挖地雷
dp 一开始按照书上的方法用dp写#include<iostream>#include<cstring>using namespace std;int main(){ long f[201]={0},w[201],c[201]={0}; bool a[201][201]={0}; long i,j,n,x,y,l,k,maxx; memset(f,0,siz
2017-12-09 18:10:10
493
原创 洛谷p1020
一道落下的题…… * Dilworth定理(然而我也不会) 第一空求最长不上升子序列(用二分查找或lower_bound) 根据上一空那个定理 求最长不下降子序列(二分或upper_bound) 具体细节看代码吧 给出朴素代码*#include<algorithm>#include<cstdio>#include<cstring>using namespace std;int
2017-12-09 17:56:59
245
原创 洛谷1004
看到这个范围 就知道非dp 莫属了 看成两个人一起走 **开一个四维数组f[i][j][k][l]代表第一个人走到ij第二个人走到kl时的最大值, 答案在f[n][n][n][n]的位置** 思路 1 找出上一个时间点的最大值 2 加上现在的位置的值 3 如果两个人的位置不同再加上另一个人的位置的值#include<iostream>#include<algorithm>
2017-12-09 17:55:10
273
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人