10月清北学堂培训 Day 3
今天是钟皓曦老师的讲授~
zhx:题很简单,就是恶心一些qwq~
T1
别人只删去一个字符都能AC,我双哈希+并查集只有40?我太菜了啊qwq
考虑到越短的字符串越难压缩,越长的字符串越好压缩,所以我们可以先压缩短的字符串,再压缩长的字符串,这就是全损压缩法:
全损压缩法:
1.先把所有的字符串读进来,然后按照长度从小到大排序;
2.为了压缩不成问题,我们应该从最短的字符串开始压缩;
3.依次从 a , b , c …… , x , y , z , aa , ab ……这样的顺序进行压缩,如果两个字符串相同就把它们压缩成相同的,可以发现这样的压缩方法一定是最优的;
- #include<cstdio>
- #include<cstdlib>
- #include<cstring>
- #include<map>
- #include<string>
- #include<iostream>
- #include<algorithm>
- using namespace std;
- const int maxn=;
- map<string,string> ma;
- string z[maxn];
- int n,l=,res[],y[maxn];
- bool cmp(int a,int b)
- {
- return z[a]<z[b];
- }
- int main()
- {
- cin >> n;
- for (int a=;a<=n;a++)
- {
- cin>>z[a];
- y[a]=a;
- }
- res[]=;
- sort(y+,y+n+,cmp);
- for (int a=;a<=n;a++)
- {
- string now = z[y[a]];
- if (ma.count(now)!=) ;
- else
- {
- string cur = "";
- for (int a=l;a>=;a--)
- cur = cur + (char)(res[a]+'a'-);
- ma[now] = cur;
- res[]++;
- for (int a=;a<=l;a++)
- if (res[a]>)
- {
- res[a]=;
- res[a+]++;
- }
- if (res[l+]) l++;
- }
- }
- for (int a=;a<=n;a++)
- cout << ma[z[a]] << endl;
- return ;
- }
T2
题意:
给了一棵有向树(外向树:所有边都是从根向外指的树就是外向树),并且在树上随便插了一条边,我们需要把这条边找出来,并保证这条边的编号尽可能的大 。
分两组情况:
1. 知道根节点是谁:
也就是能找到一个入度为 0 的点;
也就说明违和的边是从根下连到根下的,分为两种边:返祖边,横叉边;
但这两种边还是能归结到一种情况:有一个点的入度一定为 2;
我们就删掉连着这个入度为 2 的编号最大的边就好了;
2.不知道根节点是谁:
如果我们找不到一个入度为 0 的点的话,也就是说新加的那一条边的终点就是根节点;
那么会构成一个环,我们删掉环上编号最大的边删掉就好了;
- #include<cstdio>
- #include<cstdlib>
- #include<cstring>
- #include<algorithm>
- using namespace std;
- const int maxn=;
- int n,en,head,tail,in[maxn],ex[maxn][],q[maxn],f[maxn],pre[maxn][];
- bool use[maxn];
- struct edge
- {
- int s,e,p;
- edge *next;
- }*v[maxn],ed[maxn];
- void add_edge(int s,int e,int p)
- {
- en++;
- ed[en].next=v[s];v[s]=ed+en;v[s]->e=e;v[s]->p=p;
- in[e]++;
- ex[en][]=s;ex[en][]=e;
- }
- int get(int p)
- {
- if (f[p]==p) return p;
- else return get(f[p]);
- }
- void init()
- {
- en=;
- memset(v,,sizeof(v));
- memset(in,,sizeof(in));
- }
- void read()
- {
- scanf("%d",&n);
- for (int a=;a<=n;a++)
- {
- int s,e;
- scanf("%d%d",&s,&e);
- add_edge(s,e,a);
- }
- }
- bool work1(int p,int d)
- {
- memset(use,false,sizeof(use));
- use[p]=true;
- head=tail=;
- q[]=p;
- for (;head<=tail;)
- {
- int p=q[head++];
- for (edge *e=v[p];e;e=e->next)
- if (e->p!=d)
- {
- if (use[e->e]) return false;
- use[e->e]=true;
- pre[e->e][]=p;
- pre[e->e][]=e->p;
- q[++tail]=e->e;
- }
- }
- for (int a=;a<=n;a++)
- if (!use[a]) return false;
- return true;
- }
- int work2(int p)
- {
- memset(use,false,sizeof(use));
- use[p]=true;
- head=tail=;
- q[]=p;
- for (;head<=tail;)
- {
- int p=q[head++];
- for (edge *e=v[p];e;e=e->next)
- {
- if (use[e->e]) return e->p;
- use[e->e]=true;
- q[++tail]=e->e;
- }
- }
- return -;
- }
- int work()
- {
- for (int a=;a<=n;a++)
- if (in[a]==)
- {
- int p1=-,p2=-;
- for (int b=;b<=n;b++)
- if (ex[b][]==a)
- {
- if (p1==-) p1=b;
- else p2=b;
- }
- if (p1>p2) swap(p1,p2);
- for (int b=;b<=n;b++)
- if (in[b]==)
- {
- if (work1(b,p2)) return p2;
- else return p1;
- }
- }
- for (int a=;a<=n;a++)
- if (in[a]==) return work2(a);
- for (int a=;a<=n;a++)
- f[a]=a;
- for (int a=;a<=n;a++)
- {
- int f1=get(ex[a][]);
- int f2=get(ex[a][]);
- if (f1==f2)
- {
- work1(ex[a][],a);
- int p=ex[a][],ans=a;
- while (p!=ex[a][])
- {
- ans=max(ans,pre[p][]);
- p=pre[p][];
- }
- return ans;
- }
- f[f1]=f2;
- }
- return -;
- }
- int main()
- {
- init();
- read();
- int p=work();
- printf("%d\n",p);
- return ;
- }
T3
想用 dp 骗 60% 的数据来着,却成了我这三个题的最高分??
原谅我没看懂 zhx 老师的状态设置(他好像是直接设答案,不好想),我还是讲讲我的吧qwq:
状态设置:
dp [ i ][ j ]:当 Alice(下面称为 ' A ')杯内的茶剩下 i 吨, Bob(下面称为 ' B ')杯内的茶剩下 j 吨的概率是多少;
边界设置:
一开始的时候 A 和 B 都没有倒茶,所以 dp [ n ][ n ] = 1.0;
状态转移方程:
A 每次会等概率的倒出 k,2k,3k,4k 吨的茶,相应的 B 就会倒出 3k,2k,k,0 吨的茶,所以我们去枚举一下 A 倒出多少吨茶就好了:
dp [ i-x ][ j - ( 4k - x ) ] += dp [ i ][ j ] * 0.25; (i 倒出之后还剩下 i-x,j 倒出之后还剩下 j - ( 4k - x ))
- for(int i=n;i>;i--)
- for(int j=n;j>;j--)
- for(int p=k;p<=*k;p+=k)
- dp[max(i-p,)][max(j-*k+p,)]+=(double)dp[i][j]*0.25; //注意如果杯里的茶不够p的话,剩下的是0而不是一个负数
答案:
这时候就要考验大家的语文水平了:
wrong answer = ( ans1 + ans2 ) / 2;
right answer = ans1 + ( ans2 / 2 );
虽然我一开始觉得是第一种,但是通过分析样例发现原来是第二种,真是坏啊qwq
先想第一种 “ A 先把茶倒光的情况 ”:
我们设最后一次 A 倒了 x 吨的茶,那么 B 倒了 4k-x 吨的茶;
既然 A 一次就倒完了,并且 B 倒了之后还有剩余,那么也就是说倒之前 A 的杯子里的茶水是不超过 x 吨的,B 的杯子里的茶水是超过了 4k-x 吨的;
那么我们把这些所有情况加起来就好了:
- for(int p=k;p<=*k;p+=k) //A先把茶倒完的情况:枚举A最后一次倒了多少多少
- for(int i=;i<=p;i++)
- for(int j=n;j>*k-p;j--) //枚举B最后一次倒之前倒了多少
- ans1+=dp[i][j]*0.25;
然后想第二种 “ A 和 B 同时把茶倒光的情况 ”:
也就是说,最后一次倒茶时,A 的杯子内的茶水是不超过 x 吨的,同时 B 的杯子内的茶水是不超过 4k-x 吨的:
- for(int p=k;p<=*k;p+=k) //同时倒完的情况:枚举A最后一次倒了多少
- for(int i=;i<=p;i++)
- for(int j=;j<=*k-p;j++)
- ans2+=dp[i][j]*0.25;
然后输出 ans1 + ans2 / 2 就好了;
但是。。。这个题 n,k <= 1e9,你的算法是 O ( n2 ) 的 ε=(´ο`*))) 唉;
貌似 k 没用?
考虑到其实 n=10,k=2 和 n=5,k=1 是一种情况,它们的最后答案是一样的;
假如 n = 10, k = 5 和 n = 2 , k = 1 是一样的!
那么我们就可以做一个转化:
n => n / k (上取整),k => 1;
那么现在的问题就变成:给你一个 n,问概率。
打表大法好啊!而且这个题就可以打表做qwq 。
两种方法打表:
1. 爆搜,而且可以加上记忆化;
状态设置:f [ i ][ j ] :
f [ 0 ][ i ] = 1.0;
f [ i ][ 0 ] = 0.0;
f [ 0 ][ 0 ] = 0.5;
考虑怎么转移:
f [ i ][ j ] = 0.25 * ( f [ i-4 ][ j ] + f [ i-3 ][ j-1 ] + f [ i-2 ][ j-2 ] + f [ i-1 ][ j-3 ] );
然后我们可以发现,当 n 超过了 235 的时候(n/k 后的新 n),答案就是 1 了 。
所以我们再加一个特判,就满分喽~
我的 lj 代码:
- #include<iostream>
- #include<cstdio>
- #include<cstring>
- #include<cmath>
- #include<queue>
- using namespace std;
- int read()
- {
- char ch=getchar();
- int a=,x=;
- while(ch<''||ch>'')
- {
- if(ch=='-') x=-x;
- ch=getchar();
- }
- while(ch>=''&&ch<='')
- {
- a=(a<<)+(a<<)+(ch-'');
- ch=getchar();
- }
- return a*x;
- }
- int n,k;
- double dp[][];
- double ans1,ans2;
- int main()
- {
- //freopen("tea.in","r",stdin);
- //freopen("tea.out","w",stdout);
- n=read();k=read();
- if(n%k!=) n=n/k+;
- else n=n/k;
- k=;
- if(n>)
- {
- printf("1.000000");
- return ;
- }
- dp[n][n]=1.0;
- for(int i=n;i>;i--)
- for(int j=n;j>;j--)
- for(int p=k;p<=*k;p+=k)
- {
- //printf("dp[%d][%d]:%lf\n",i,j,dp[i][j]);
- dp[max(i-p,)][max(j-*k+p,)]+=(double)dp[i][j]*0.25;
- //printf("dp[%d][%d]:%lf\n",max(i-p,0),max(j-4*k+p,0),dp[max(i-p,0)][max(j-4*k+p,0)]);
- }
- for(int p=k;p<=*k;p+=k) //A先把茶倒完的情况:枚举A最后一次倒了多少多少
- for(int i=;i<=p;i++)
- for(int j=n;j>*k-p;j--) //枚举B最后一次倒之前倒了多少
- ans1+=dp[i][j]*0.25;
- for(int p=k;p<=*k;p+=k) //同时倒完的情况:枚举A最后一次倒了多少
- for(int i=;i<=p;i++)
- for(int j=;j<=*k-p;j++)
- ans2+=dp[i][j]*0.25;
- //printf("%lf %lf\n",ans1,ans2);
- printf("%.6lf",ans1+ans2*0.5);
- return ;
- }
标程超短代码:
- #include<cstdio>
- #include<cstdlib>
- #include<cstring>
- using namespace std;
- const int maxn=;
- int n,k;
- double f[maxn][maxn];
- bool g[maxn][maxn];
- double dfs(int n,int m)
- {
- if (n<= && m<=) return 0.5;
- if (n<=) return 1.0;
- if (m<=) return 0.0;
- if (g[n][m]) return f[n][m];
- g[n][m]=true;
- for (int a=;a<=;a++)
- f[n][m]+=0.25*dfs(n-a,m-+a);
- return f[n][m];
- }
- double work(int n,int k)
- {
- if (n/k>=maxn) return 1.0;
- return dfs((n/k)+(n%k?:),(n/k)+(n%k?:));
- }
- int main()
- {
- scanf("%d%d",&n,&k);
- printf("%.6lf\n",work(n,k));
- return ;
- }
图论题选讲
Problem -1 是什么操作?
先假设没有障碍的情况:
因为在同一行或同一列的两个物体能互相看见,也就是说一个物体会用掉一行和一列;
如果我们从第 i 行连向了第 j 列,那么就说明 (i,j)这个位置可以放上物体;
我们放上一个障碍物,就可以看做把那一行和列分成了两个部分;
最后答案:我们最多能匹配多少对,就是我们最多能放多少个物体;
一遍匈牙利算法或网络流 Dinic 算法跑最大匹配就好了;
考虑到一开始的两个 1 既不能在同一行,也不能在同一列;
所以我们只需要判断是否有 n 个 1 都不在同一行或同一列上;
这就类似于上一个题啊qwq;
第 i 行连向第 j 列表示(i,j)这个位置的 1 可以选;
最后我们只需要看看最大匹配数是否是 n 就好了;
如果我们找不到的话,就说明无解!
2-SAT 问题:
有 n 个变量,每一个变量都是 bool 类型的,除了这 n 个变量以外,我们还有 m 个关系表达式,关系表达式差不多是这样的:
x1 & x2 = false(注意每个表达式只会有两个变量)
问给出 m 个关系表达式后,能否给这 n 个变量找出一个赋值的方法,使得满足所有的表达式;
核心问题只需要考虑有没有解;
对于每个变量都只有两种取值:0 / 1,那么对于每个点,我们把每个变量看成 0点和 1点;
假如我们有一个关系:x1 & x2 = false;
说明 x1 和 x2 中一定有一个为 false;
那么我们可以从 x1 的 true 连向 x2 的 false,从 x2 的 true 连向 x1 的 false;
要注意只有关系明确的时候才能建边;
解释一下:
如果 x1 的值为 true ,那么如果我们 x2 的值再为 true 的话,就不满足 “ x1 & x2 = false ” 这个式子了,所以如果 x1 为 true 的话是能明确推出 x2 为 false 的;
我们可以从 x2 的 flase 向 x1 的 true 连边吗?这样也能满足关系式;
显然不能,因为你如果 x2 为 false 的话,x1 为 true 或 false 是都可以的,这不是明确的关系,我们不能建边;
所以一般的建边方式为:
若 xa = p 或 xb = q 中至少有一个满足,那么我们建两条边:
xa (¬p) -> xb (q)
xb (¬q) -> xa (p)
如果一个变量必须等于 true,那么我们从这个点的 false 连向这个点的 true;
表示我们从 false 走也会走到 true,也就是说只能等于 true;
怎么判断是否有解?
假如说我们从一个点的 true 走到了它自己的 false,那么就说明这个点只能是 false;假如我们从一个点的 false 走到了它自己的 true,那么久说明这个点只能是 true;以上两种情况是有解的 。
无解的情况就是:某一个变量的 false 能走到 true,从 true 也能走到 false,也就是说,某一个变量的两个取值在同一个强连通分量内的话,就说明无解。
所有的 2-SAT 问题都是这么做;
最大化最小值问题,二分喽~
二分爆炸半径的最小值 r,看 r 是否合法;
既然最小值是 r 了,我们不妨直接让所有的炸弹的爆炸范围都是 r;
我们看到每一组都有两种取值,自然对应得就是 2-SAT 了;
建图:
假如我们第一组的第一个炸弹能扎到第二组的第一个炸弹,那么就说明这两个炸弹不能同时选,所以我们从第一组的第一个炸弹向第二组的第二个炸弹连一条边;反之,我们从第一组的第二个炸弹向第二组的第一个炸弹连边;(注意连有向边)
每次 n2 暴力建边,然后 tarjan 判断是否合法就好了;
合法就向更大的 r 去枚举,直至不合法 ,此时的 r 就是答案了。
给你一个 n * m 的棋盘,上面有些格子是黑色的,有些格子是白色的,还有一些障碍(不能放骨牌),现在你有一种类似于 ' L ' 型的骨牌,两端是白色的,中间是黑色的,要求将骨牌放在棋盘上,使得黑色部分放在黑色格子上,白色部分放在白色格子上,每个格子只能被覆盖一次(只能放一个骨牌),问能否能将整个棋盘覆盖满?
我们考虑将黑点拆点,使得一个黑格子对于一个白格子;
但是有一个问题:我们可能搞出来的不是 ' L ' 型;
所以我们将白格子分为上下白格子和左右白格子;
这样的话,一个黑格子对应一个上下白格子,一个黑格子对应一个左右白格子,合起来的话就能保证它是一个 ' L ' 型的了;
对于更大的数据,只能用 2-SAT 做了:
看到这道题只是判断有没有解,那么自然就想到了 2-SAT 。
我们可以为每个黑点造两个变量:左右变量和上下变量,每个变量有两种取值,这样就变成了 2-sat 问题 。
点建好了,边怎么建?
如果两个黑格子的曼哈顿距离不超过 2,它们之间就有可能会冲突:
假设我们有两个黑格子的分布是:左上和右下,那么它们的建边关系就是:
实际也就 6 种情况,我们分别根据它们的位置关系建边就可以了:
然后我们跑一遍 tarjan 判断其是否有解;
总时间复杂度 O ( nm );
我们依然可以用 2-SAT 做;
我们考虑每个提案到底是通过还是否决;
我们先考虑每个人投一票的情况:
假如一个人对了一号提案投了反对票,由于要有一半以上的提案和投票情况相符,所以这个提案一定否决,我们从一号提案的通过连向否决,表示一号提案一定被否决:
发现投两票和投一票的情况一样,也是需要所投的两个提案必须都和投票情况相符;
考虑投三票的情况:假设一个人投了三、四、五号提案的通过,假如三号提案被否决了,由于至少要有一半以上的提案符合投票情况,所以剩下的四、五号提案是一定被通过的,所以我们可以从三号提案的否决分别连向四、五号提案的通过;同理我们再从四号提案的否决连向三、五号提案的通过,从五号提案的否决连向三、四号提案的通过:
发现投四票的情况也是和投三票的情况一样,一个不满足剩下的三个都必须满足;
答案:
如果一个提案能从通过走到否决,那么说明这个提案一定会被否决;如果一个提案能从否决走到通过,那么说明这个提案一定会被通过;如果既能从通过走到否决,也能从否决走到通过,那么说明这个提案不一定被通过或者否决;
由于树是个二分图,所以我们可以从树的角度去考虑; 把一张图变成一棵树有两种方法:
1.生成树;
2.缩点;
一张图如果不是二分图,就说明有基环存在,所以我们要把所有的基环都干掉,所以我们所需要干掉的这条边就是所有基环的交集的那条边;
那么怎么求所有基环的交集?
我们先在这个图上随便求一棵生成树,然后我们求完生成树后,所有的边分成了两类:树边和非树边;
如果没有不在树上的边,就说明这个图是二分图了;如果有一条不在树上的边,连了两个颜色一样的点,形成了一个基环,我们需要破坏掉基环;
如果我们只能找到一条非树边,那就说明这一张图里面就一个基环,那么我们删掉这个基环上的任意一条边都可以使这个图变成二分图;
如果说存在两条及以上的基环,我们并不能通过删除一条非树边来搞掉所有基环,此时我们要删的就是一条树边;
如果一条非树边形成了一个基环,我们就将这个基环上的所有边的权值+1;这么瞎搞一通以后,如果我们发现有一条树边的权值等于基环的个数,也就是说这条树边被所有的基环包含在内,所以这一条边就是答案了;
至于+1的操作,我们可以使用树上差分或者树链剖分来实现;
看着 A 国人少条件少,先欺负分析 A 国:
化简一下 A 国交朋友的条件:
x1 ^ x2 %2 = 1;
保证两个友善值异或后是奇数,也就是说两个数表示成二进制后最右边的那一位不同,也就是说两个人的友善值一奇一偶;
那么最后的朋友圈中 A 国就只有 2 个人(超过了2人的话肯定有两个人的奇偶性相同,那么就不会是朋友了);
所以现在的问题就是找 B 国最大的朋友圈;
给你一张图让你求最大团是 NPC 问题,那么这个图不是随便给你的,一定是含有某个神奇的性质的;
我们来分析 B 国交朋友的条件:
第一个条件:x1 ^ x2 % 2 = 0;
与 A 国的分析情况相似,也就是说友善值同奇偶的人可以互相交朋友;
第二个条件:x1 | x2 在二进制表示上有奇数个1;
这个条件看起来有点奇怪,但可以确定的是这个条件使得在 B 国一奇一偶的人也可以交朋友,那么总体来说 B 国的情况就是这个亚子:
看这个亚子有点像二分图呐,但是我们知道二分图两侧的点之间是没有连边的呀,但是这个图却两两连了边(没画全,其实是不想画了,意思意思就好),然后我们发现这个图的补图是一个二分图!
二分图的补图:
反图的最大独立集就是原图的最大团;
我们要在补图中找到一个最大的独立集,使得原图求出来的是最大团;
每有一个匹配,我们所能够选的点就少一个,所以最后的答案就是:n+m - 最大匹配;
每种颜色的格子最多两个?神奇的数字 2!
假设我们考虑每种颜色的格子只有 1 个的话,那么每种颜色的格子要去的方向是固定的;
那么我们肯定能通过 “ 行操作 + 列操作 + 行操作 ” 或 “ 列操作 + 行操作 + 列操作 ” 来完成;
那么最后的答案一定不超过:min(ca+2cb ,cb + 2ca);
如果只有一个系列的操作,我们直接通过暴力去求;
如果需要通过两个系列去解决呢?
如果我们发现同一行的两个格子要到同一列去,或者同一列的两个格子要去同一行去,那么我们就不能省去第三步;
但是原题每种颜色都至少有 2 个呀?
我们可以 dfs 每个格子去哪里,但是这样的话时间复杂度为 O ( 245000 );
假设一种颜色的两个初始位置 a,b ,在目标状态移动到了 A,B;
那么只有两种取值:
1. a -> A,b -> B;
2. a -> B,b -> A;
如果 a 和 c 在同一行,A 和 C 在同一列,那么就说明我们不能通过两部操作来完成;
如果 a 去 A , b 去 B,那么 c 只能去 D,同样 d 去 c;
如果 a 去 B , b 去 A,那么 c 只能去 C,同样 d 去 D;
10月清北学堂培训 Day 3的更多相关文章
- 10月清北学堂培训 Day 7
今天是黄致焕老师的讲授~ 历年真题选讲 NOIP 2012 开车旅行 小 A 和小 B 决定外出旅行,他们将想去的城市从 1 到 n 编号,且编号较小的城市在编号较大的城市的西边.记城市 i 的海拔高 ...
- 10月清北学堂培训 Day 6
今天是黄致焕老师的讲授~ T1 自信 AC 莫名 80 pts???我还是太菜了!! 对于每种颜色求出该颜色的四个边界,之后枚举边界构成的矩阵中每个元素,如果不等于该颜色就标记那种颜色不能最先使用. ...
- 10月清北学堂培训 Day 5
今天是廖俊豪老师的讲授~ T1 第一次想出正解 30 pts: k <= 10,枚举如何把数放到矩阵中,O ( k ! ): 100 pts: 对于矩阵的每一列,我们二分最小差异值,然后贪心去判 ...
- 10月清北学堂培训 Day 4
今天是钟皓曦老师的讲授~ 今天的题比昨天的难好多,呜~ T1 我们需要找到一个能量传递最多的异构体就好了: 整体答案由花时间最多的异构体决定: 现在的问题就是这么确定一个异构体在花费时间最优的情况下所 ...
- 10月清北学堂培训 Day 2
今天是杨溢鑫老师的讲授~ T1 物理题,不多说(其实是我物理不好qwq),注意考虑所有的情况,再就是公式要推对! #include<bits/stdc++.h> using namespa ...
- 10月清北学堂培训 Day 1
今天是杨溢鑫老师的讲授~ T1 1 题意: n * m 的地图,有 4 种不同的地形(包括空地),6 种不同的指令,求从起点及初始的状态开始根据指令行动的结果. 2 思路:(虽然分了数据范围但是实际上 ...
- 7月清北学堂培训 Day 3
今天是丁明朔老师的讲授~ 数据结构 绪论 下面是天天见的: 栈,队列: 堆: 并查集: 树状数组: 线段树: 平衡树: 下面是不常见的: 主席树: 树链剖分: 树套树: 下面是清北学堂课程表里的: S ...
- 8月清北学堂培训 Day6
今天是杨思祺老师的讲授~ 图论 双连通分量 在无向图中,如果无论删去哪条边都不能使得 u 和 v 不联通, 则称 u 和 v 边双连通: 在无向图中,如果无论删去哪个点(非 u 和 v)都不能使得 u ...
- 8月清北学堂培训 Day2
今天是赵和旭老师的讲授~ 背包 dp 模型 背包 dp 一般是给出一些“物品”,每个物品具有一些价值参数和花费参数,要求 在满足花费限制下最大化价值或者方案数. 最简单几种类型以及模型: 0/1背包: ...
随机推荐
- 正整数序列 Help the needed for Dexter ,UVa 11384
题目描述 Description 给定正整数n,你的任务是用最少的操作次数把序列1, 2, …, n中的所有数都变成0.每次操作可从序列中选择一个或多个整数,同时减去一个相同的正整数.比如,1,2,3 ...
- 使用postman mock server
需要写一个小的Java程序,用来调用云平台的接口 由于云平台的接口程序还没有写好,只能用模拟的方式先行开发代码, 用了post来模拟接口程序. 需要模拟的接口如下: ■请求地址 /openapi/ip ...
- codeforce 849D. Make a Permutation!
D. Make a Permutation! time limit per test 2 seconds memory limit per test 256 megabytes input stand ...
- springMVC关于异常优先级的处理
优先级 既然在SpringMVC中有两种处理异常的方式,那么就存在一个优先级的问题: 当发生异常的时候,SpringMVC会如下处理: (1)SpringMVC会先从配置文件找异常解析器Handler ...
- ubuntu环境下pycharm编译程序import包出错:ImportError: dynamic module does not define init function (init_caffe)
出错原因是因为pycharm中的python版本不对,比如程序为2.7版本,但是pycharm编解释器为python3,导致出错,去setting改一下版本就行:pycharm>file> ...
- 查询并批量插入数据的Sql命令
INSERT INTO student(id,xuesheng,yuwen,shuxue,yingyu) SELECT id,xuesheng,yuwen,shuxue,yingyu FROM stu ...
- javascript/js实现 排序二叉树数据结构 学习随笔
二叉树是一种数据结构.其特点是: 1.由一系列节点组成,具有层级结构.每个节点的特性包含有节点值.关系指针.节点之间存在对应关系. 2.树中存在一个没有父节点的节点,叫做根节点.树的末尾存在一系列没有 ...
- arm9交叉编译工具链
Arm-linux-gcc: gcc和arm-linux-gcc的头文件并不一样. Eg. Arm-linux-ld:链接器,-T参数是使用链接器脚本. Eg. Arm-linux-readelf:读 ...
- OpenStack kilo版(7) 部署dashboard
安装dashboard root@controller:~# apt-get install openstack-dashboard 配置 /etc/openstack-dashboard/loc ...
- [LeetCode] 45. Jump game II ☆☆☆☆☆(跳跃游戏 2)
https://leetcode-cn.com/problems/jump-game-ii/solution/xiang-xi-tong-su-de-si-lu-fen-xi-duo-jie-fa-b ...