(自己的理解:首先考虑单调队列,不行时考虑斜率,再不行就考虑不等式什么的东西)

当dp的状态转移方程dp[i]的状态i需要从前面(0~i-1)个状态找出最优子决策做转移时 我们常常需要双重循环

(一重循环跑状态 i,一重循环跑 i 的所有子状态)这样的时间复杂度是O(N^2)而 斜率优化或者四边形不等式优化后的DP

可以将时间复杂度缩减到O(N)

O(N^2)可以优化到O(N) ,O(N^3)可以优化到O(N^2),依次类推

斜率优化DP和四边形不等式优化DP主要的原理就是利用斜率或者四边形不等式等数学方法

在所有要判断的子状态中迅速做出判断,所以这里的优化其实是省去了枚举i的子状态的循环,几乎就是直接把最优的子状态找出来了

其中四边形不等式优化是用数组s边跑边求最优的子状态,例如用s[i][j]保存dp[i][j]的最优子状态

斜率优化的话是将后面可能用到的子状态放到队列中,要求的当前状态的最优状态就是队首元素q[head]

另外,网上见到很多用二分+DP解斜率优化的问题。

以dp求最小值为例:

主要的解题步骤就是先写出dp的状态转移方程,然后选取两个子状态p,q

假设p < q而决策q比p更好,求出斜率不等式,然后就可以写了

至于经常有题目控制子决策的范围什么的(比如控制区间长度,或者控制分组的组数),就需要具体情况具体分析

1  HDU 1300 Pearls

最最最简单的斜率DP优化的题,就算不用优化,O(N^2)的算法也可以AC

这题绝壁是最最最适合入门的斜率DP的题,我发誓!!!

版本一:(O(N^2))

#define mem(a,x) memset(a,x,sizeof(a))
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<set>
#include<stack>
#include<cmath>
#include<map>
#include<stdlib.h>
#include<cctype>
#include<string>
#define Sint(n) scanf("%d",&n)
#define Sll(n) scanf("%I64d",&n)
#define Schar(n) scanf("%c",&n)
#define Schars(s) scanf("%s",s)
#define Sint2(x,y) scanf("%d %d",&x,&y)
#define Sll2(x,y) scanf("%I64d %I64d",&x,&y)
#define Pint(x) printf("%d",x)
#define Pllc(x,c) printf("%I64d%c",x,c)
#define Pintc(x,c) printf("%d%c",x,c)
using namespace std;
typedef long long ll;
/*
dp[i]表示买前i种珍珠的最少花费 dp[i] = min(dp[j] + (sum[i] - sum[j] + 10)*w[i])
其中sum[i]-sum[j]表示第j+1种珍珠到第i种珍珠所需的数量
w[i]表示第i种珍珠的价值 */
const int N = ;
int w[N],dp[N],sum[N];
int main()
{
int T;Sint(T);
while (T--)
{
int n;Sint(n);
for (int i = ,x;i <= n;++i)
{
Sint2(x,w[i]);
sum[i] = sum[i-] + x;
}
dp[] = (sum[]+)*(w[]);
for (int i = ;i <= n;++i)
{
dp[i] = dp[i-] + (sum[i]-sum[i-]+)*w[i];
for (int j = ;j < i-;++j)
{
dp[i] = min(dp[i],dp[j] + (sum[i]-sum[j]+)*w[i]);
}
}
Pintc(dp[n],'\n');
}
return ;
}

当做出暴力DP版本之后,只需再多考虑一步就可以变成斜率优化DP

对于状态转移方程dp[i] = dp[j] + (sum[i]-sum[j]+10)*w[i]

考虑 k < j < i 且假设 i状态由j状态转移得到比由k状态转移得到更优

即:dp[j] + (sum[i]-sum[j]+10)*w[i] <= dp[k] + (sum[i] - sum[k] + 10)*w[i]

(这里取小于号是因为dp保存的是最小花费,花费越小越好,取等是因为j比k大,所以就算k,j一样优也选j)

这个不等式化简之后就是

dp[j] - dp[k] <= w[i]*(sum[j]-sum[k])

这里的w[i]满足单调递增

有了上面的不等式和单调条件就可以斜率优化了,主要做法就是利用单调队列维护满足的点

比如j状态优于k状态,就可以将k永远的剔除了

具体对于子状态的维护见代码里面有2个对队列进行的删除的操作,一个是在求dp[i]时在队首删除

一个是在将状态i加入队列时在队尾删除的操作

版本二:(O(N))

#define mem(a,x) memset(a,x,sizeof(a))
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<set>
#include<stack>
#include<cmath>
#include<map>
#include<stdlib.h>
#include<cctype>
#include<string>
#define Sint(n) scanf("%d",&n)
#define Sll(n) scanf("%I64d",&n)
#define Schar(n) scanf("%c",&n)
#define Schars(s) scanf("%s",s)
#define Sint2(x,y) scanf("%d %d",&x,&y)
#define Sll2(x,y) scanf("%I64d %I64d",&x,&y)
#define Pint(x) printf("%d",x)
#define Pllc(x,c) printf("%I64d%c",x,c)
#define Pintc(x,c) printf("%d%c",x,c)
using namespace std;
typedef long long ll;
/*
dp[i]表示买前i种珍珠的最少花费 dp[i] = min(dp[j] + (sum[i] - sum[j] + 10)*w[i])
其中sum[i]-sum[j]表示第j+1种珍珠到第i种珍珠所需的数量
w[i]表示第i种珍珠的价值 dp[j] - dp[k] <= w[i]*(sum[j]-sum[k])
The qualities of the classes (and so the prices) are given in ascending order.
So w[i]单增 --斜率DP
*/
const int N = ;
int w[N],dp[N],sum[N];
int q[N];
int DP(int i,int j)
{
return dp[j] + (sum[i]-sum[j]+)*w[i];
}
int dy(int i,int j)
{
return dp[i]-dp[j];
}
int dx(int i,int j)
{
return sum[i]-sum[j];
}
int main()
{
int T;Sint(T);
while (T--)
{
int n;Sint(n);
for (int i = ,x;i <= n;++i)
{
Sint2(x,w[i]);
sum[i] = sum[i-] + x;
}
int head = ,tail = ;
q[tail++] = ;
for (int i = ;i <= n;++i)
{
while (head+<tail&&dy(q[head+],q[head])<=w[i]*dx(q[head+],q[head])) ++head;
dp[i] = DP(i,q[head]);
while (head+<tail&&dy(i,q[tail-])*dx(q[tail-],q[tail-])<=dy(q[tail-],q[tail-])*dx(i,q[tail-])) --tail;
q[tail++] = i;
}
Pintc(dp[n],'\n');
}
return ;
}

POJ 1260 Pearls   和上面一题一样的

3.HDU 3507 Print Article

 
列状态转移方程 然后假设 k < j < i 且j决策更好 不等式列出来就好了
#define mem(a,x) memset(a,x,sizeof(a))
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<set>
#include<stack>
#include<cmath>
#include<map>
#include<stdlib.h>
#define Sint(n) scanf("%d",&n)
#define Sll(n) scanf("%I64d",&n)
#define Schar(n) scanf("%c",&n)
#define Sint2(x,y) scanf("%d %d",&x,&y)
#define Sll2(x,y) scanf("%I64d %I64d",&x,&y)
#define Pint(x) printf("%d",x)
#define Pllc(x,c) printf("%I64d%c",x,c)
#define Pintc(x,c) printf("%d%c",x,c)
using namespace std;
typedef long long ll;
const int N = ;
int dp[N];
int sum[N];
int q[N];
int n,m;
int EX(int x)
{
return x*x;
}
int getDP(int i,int j)
{
return dp[j] + m + EX(sum[i]-sum[j]);
}
int getUP(int j,int k)//yj - yk
{
return (dp[j] + EX(sum[j])) - (dp[k] + EX(sum[k]));
}
int getDown(int j,int k)//xj - xk
{
return *(sum[j] - sum[k]);
}
int main()
{ while (Sint2(n,m) == )
{
for (int i = ,x;i <= n;++i)
{
Sint(x);
sum[i] = sum[i-] + x;
}
int head = ,tail = ;
q[tail++] = ;//单调队列 (单增)
for (int i = ;i <= n;++i)
{
// getup/getdown <= sum[i]
while (head+<tail&&getUP(q[head+],q[head])<=sum[i]*getDown(q[head+],q[head])) head++;
dp[i] = getDP(i,q[head]);
// getup(i,q[tail-1])/getdown(i,q[tail-1]) <= getup(q[tail-1],q[tail-2])/getdown(q[tail-1],q[tail-2])
while (head+<tail&&getUP(i,q[tail-])*getDown(q[tail-],q[tail-])<=getUP(q[tail-],q[tail-])*getDown(i,q[tail-]))tail--;
q[tail++] = i;
}
Pintc(dp[n],'\n');
}
return ;
}

4.HDU 2829 Lawrence

#define mem(a,x) memset(a,x,sizeof(a))
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<set>
#include<stack>
#include<cmath>
#include<map>
#include<stdlib.h>
#include<cctype>
#include<string>
#define Sint(n) scanf("%d",&n)
#define Sll(n) scanf("%I64d",&n)
#define Schar(n) scanf("%c",&n)
#define Sint2(x,y) scanf("%d %d",&x,&y)
#define Schars(s) scanf("%s",s)
#define Sll2(x,y) scanf("%I64d %I64d",&x,&y)
#define Pint(x) printf("%d",x)
#define Pllc(x,c) printf("%I64d%c",x,c)
#define Pintc(x,c) printf("%d%c",x,c)
using namespace std;
typedef long long ll;
/*
dp[i][j]表示前j个数分成i组的最小价值
sum[i]表示前i个数的和
cost[i]表示前i个数的花费
*/
const int N = ;
int sum[N],cost[N],dp[N][N];
int q[N],head,tail;
int n,m;
int EX(int x)
{
return x*x;
}
int dy(int x,int j,int i)
{
return dp[x][i] - cost[i] + EX(sum[i]) - (dp[x][j] - cost[j] + EX(sum[j]));
}
int dx(int j,int i)
{
return sum[i] - sum[j];
}
int DP(int x,int j,int i)
{
return dp[x][i]+cost[j] - cost[i] - sum[i]*(sum[j]-sum[i]);
}
int main()
{
while (Sint2(n,m)==&&(n||m))
{
++m;
for (int i = ,x;i <= n;++i)
{
Sint(x);
sum[i] = sum[i-] + x;
cost[i] = cost[i-] + sum[i-]*x;
}
for (int i = ;i <= n;++i) dp[][i] = cost[i];
for(int i = ;i <= m;++i)
{
head = tail = ;
q[tail++] = i-;
for (int j = i;j <= n;++j)
{
while (head+<tail&&dy(i-,q[head],q[head+])<=sum[j]*dx(q[head],q[head+])) head++;
dp[i][j] = DP(i-,j,q[head]);
while (head+<tail&&dx(q[tail-],q[tail-])*dy(i-,q[tail-],j)<=dy(i-,q[tail-],q[tail-])*dx(q[tail-],j)) --tail;
q[tail++] = j;
}
}
Pintc(dp[m][n],'\n');
}
return ;
}

5.UVALive 5097 - Cross the Wall

#define mem(a,x) memset(a,x,sizeof(a))
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<set>
#include<stack>
#include<cmath>
#include<map>
#include<stdlib.h>
#include<cctype>
#include<string>
#define Sint(n) scanf("%d",&n)
#define Sll(n) scanf("%lld",&n)
#define Schar(n) scanf("%c",&n)
#define Schars(s) scanf("%s",s)
#define Sint2(x,y) scanf("%d %d",&x,&y)
#define Sll2(x,y) scanf("%lld %lld",&x,&y)
#define Pint(x) printf("%d",x)
#define Pllc(x,c) printf("%lld%c",x,c)
#define Pintc(x,c) printf("%d%c",x,c)
using namespace std;
typedef long long ll;
/*
dp[i][j]表示 前i个人挖j个洞的最小花费
1.当w[i] <= w[j] && h[i]<=h[j]时 舍弃 (w[i],h[i])
2.将人按w递增 h递减 排序,即满足 w[j] < w[i]&&h[j] > h[i] 故dp[i][j] = dp[k][j-1] + w[i]*h[k+1] */
const int N = ; struct Node
{
ll h,w;
}b[N];
int q[N],head,tail;
bool cmp(Node a,Node b)
{
if (a.h == b.h) return a.w > b.w;
return a.h > b.h;//确保h递减
}
ll dp[N][];
ll dy(int j,int k,int t)
{
return dp[j][t] - dp[k][t];
}
ll dx(int j,int k)
{
return b[k+].h - b[j+].h;
}
int main()
{
int n,k;
while (Sint2(n,k) == )
{
for (int i = ;i <= n;++i)
{
Sll2(b[i].w,b[i].h);
}
sort(b+,b+n+,cmp);
int t = ;
for (int i = ;i <= n;++i)
{
if (b[t].w < b[i].w) b[++t] = b[i];
}
// cout<<t<<endl;
k = min(t,k);
for (int i = ;i <= t;++i) dp[i][] = b[i].w*b[].h;
for (int j = ;j <= k;++j)
{
head = tail = ;mem(q,);
q[tail++] = ;
for (int i = ;i <= t;++i)
{
while (head+<tail&&dy(q[head+],q[head],j-) <= b[i].w * dx(q[head+],q[head])) ++head;
dp[i][j] = dp[q[head]][j-] + b[i].w * b[q[head]+].h;
while (head+<tail&&dy(i,q[tail-],j-)*dx(q[tail-],q[tail-]) <= dy(q[tail-],q[tail-],j-)*dx(i,q[tail-])) --tail;
q[tail++] = i;
}
}
ll ans = dp[t][];
for (int i = ;i <= k;++i)
{
ans = min(ans,dp[t][i]);
}
Pllc(ans,'\n');
}
return ;
}

6.HDU 3045 Picnic Cows

#define mem(a,x) memset(a,x,sizeof(a))
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<set>
#include<stack>
#include<cmath>
#include<map>
#include<stdlib.h>
#include<cctype>
#include<string>
#define Sint(n) scanf("%d",&n)
#define Sll(n) scanf("%I64d",&n)
#define Schar(n) scanf("%c",&n)
#define Schars(s) scanf("%s",s)
#define Sint2(x,y) scanf("%d %d",&x,&y)
#define Sll2(x,y) scanf("%I64d %I64d",&x,&y)
#define Pint(x) printf("%d",x)
#define Pllc(x,c) printf("%I64d%c",x,c)
#define Pintc(x,c) printf("%d%c",x,c)
using namespace std;
typedef long long ll;
/*
Cows in the same team should reduce their Moo~ to the one who has the lowest Moo~ in this team dp[i]表示前i头牛的最小花费
dp[i] = dp[j] + (sum[i]-sum[j]-(i-j)*a[j+1])
dp[j]-dp[k]+sum[k]-sum[j]+j*a[j+1]-k*a[k+1] < i*(a[j+1]-a[k+1])
*/
const int N = ;
ll dp[N],a[N],sum[N];
int q[N],head,tail;
ll dy(int j,int k)
{
return dp[j]-dp[k] + sum[k]-sum[j] + j*a[j+]-k*a[k+];
}
ll dx(int j,int k)
{
return a[j+] - a[k+];
}
ll DP(int i,int j)
{
return dp[j] + (sum[i]-sum[j]-(i-j)*a[j+]);
}
int main()
{
int n,t;
while (Sint2(n,t) == )
{
for (int i = ;i <= n;++i) Sll(a[i]);
sort(a+,a+n+);
for (int i = ;i <= n;++i) sum[i] = sum[i-] + a[i];
head = tail = ;
q[tail++] = ;
for (int i = ;i <= n;++i)
{
while (head+<tail&&dy(q[head+],q[head]) <= i*dx(q[head+],q[head])) ++head;
dp[i] = DP(i,q[head]);
int j = i-t+;
if (j < t) continue;
while (head+<tail&&dy(j,q[tail-])*dx(q[tail-],q[tail-])<=dy(q[tail-],q[tail-])*dx(j,q[tail-])) --tail;
q[tail++] = j;
}
Pllc(dp[n],'\n');
}
return ;
}

7.HDU 3516 Tree Construction

斜率DP写的怎么都过不了,最后用四边形不等式,要保证j-i递增于是枚举长度

#define mem(a,x) memset(a,x,sizeof(a))
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<set>
#include<stack>
#include<cmath>
#include<map>
#include<stdlib.h>
#include<cctype>
#include<string>
#define Sint(n) scanf("%d",&n)
#define Sll(n) scanf("%I64d",&n)
#define Schar(n) scanf("%c",&n)
#define Schars(s) scanf("%s",s)
#define Sint2(x,y) scanf("%d %d",&x,&y)
#define Sll2(x,y) scanf("%I64d %I64d",&x,&y)
#define Pint(x) printf("%d",x)
#define Pllc(x,c) printf("%I64d%c",x,c)
#define Pintc(x,c) printf("%d%c",x,c)
using namespace std;
typedef long long ll;
/*
dp[i][j]表示从i到j所需的最小花费
dp[i][j] = min {dp[i][k] + dp[k+1][j] + w(i,k,j)}
w(i,k,j) = y[k] - y[j] + x[k+1] - x[i]
s[i][j] = k 表示 dp[i][j]这个状态最优的决策是 k
*/
const int N = ;
const int inf = 0x3f3f3f3f;
int dp[N][N],s[N][N];
int x[N],y[N];
int w(int i,int k,int j)
{
if (k >= j) return inf;
return y[k] - y[j] + x[k+] - x[i];
}
int DP(const int &n)
{
mem(dp,);int tmp;
for (int L = ;L<=n;++L) //以j-i递增为顺序递推
{
for (int i = ,j = L;i+L-<=n;++i,j = i+L-)//i 是 区间左端点,j是区间右端点
{
dp[i][j] = inf;
for (int k = s[i][j-];k <= s[i+][j];++k)
{
tmp = dp[i][k] + dp[k+][j] + w(i,k,j);
if (tmp < dp[i][j])
{
dp[i][j] = tmp;
s[i][j] = k;
}
}
}
}
return dp[][n];
}
int main()
{
int n;
while (Sint(n) == )
{
for (int i = ;i <= n;++i)
{
Sint2(x[i],y[i]);
s[i][i] = i;
}
Pintc(DP(n),'\n');
}
return ;
}

8.POJ 1160 Post Office

状态转移方程写的好的话不用优化也可以过

这个题的状态转移的方程很经典啊

9.POJ 1180 Batch Scheduling

#define mem(a,x) memset(a,x,sizeof(a))
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<set>
#include<stack>
#include<cmath>
#include<map>
#include<stdlib.h>
#include<cctype>
#include<string>
#define Sint(n) scanf("%d",&n)
#define Sll(n) scanf("%I64d",&n)
#define Schar(n) scanf("%c",&n)
#define Schars(s) scanf("%s",s)
#define Sint2(x,y) scanf("%d %d",&x,&y)
#define Sll2(x,y) scanf("%I64d %I64d",&x,&y)
#define Pint(x) printf("%d",x)
#define Pllc(x,c) printf("%I64d%c",x,c)
#define Pintc(x,c) printf("%d%c",x,c)
using namespace std;
typedef long long ll;
const int inf = 0x3f3f3f3f;
/*
dp[i]表示前i个job的最小花费
dp[i] = dp[j] + (S+sumt[i] - sumt[j]) *(sumf[i]-sumf[j])
*/
const int N = ;
ll dp[N];
ll sumt[N],sumf[N];
ll t[N],f[N];
int S,n;
int q[N],head,tail;
ll dy(int j,int k)
{
return dp[j] - dp[k];
}
ll dx(int j,int k)
{
return sumt[j] - sumt[k];
}
ll DP(int i,int j)
{
return dp[j] + (S + sumt[i]-sumt[j])*sumf[i];
}
int main()
{
while (Sint2(n,S) == )
{
for (int i = n;i >= ;--i) Sll2(t[i],f[i]);
for (int i = ;i <= n;++i)
{
sumt[i] = sumt[i-] + t[i];
sumf[i] = sumf[i-] + f[i];
}
head = tail = ;
q[tail++] = ;
for (int i = ;i <= n;++i)
{
while (head+<tail&&dy(q[head],q[head+])>dx(q[head],q[head+])*sumf[i]) ++head;
dp[i] = DP(i,q[head]);
while (head+<tail&&dy(q[tail-],i)*dx(q[tail-],q[tail-])<dy(q[tail-],q[tail-])*dx(q[tail-],i)) --tail;
q[tail++] = i;
}
Pllc(dp[n],'\n');
}
return ;
}

长路漫漫,其修远兮,ORZ

【转】斜率优化DP和四边形不等式优化DP整理的更多相关文章

  1. HDU 2829 Lawrence (斜率优化DP或四边形不等式优化DP)

    题意:给定 n 个数,要你将其分成m + 1组,要求每组数必须是连续的而且要求得到的价值最小.一组数的价值定义为该组内任意两个数乘积之和,如果某组中仅有一个数,那么该组数的价值为0. 析:DP状态方程 ...

  2. 区间DP的四边形不等式优化

    今天上课讲DP,所以我学习了四边形不等式优化(逃 首先我先写出满足四边形不等式优化的方程:

  3. 区间dp之四边形不等式优化详解及证明

    看了那么久的四边形不等式优化的原理,今天终于要写一篇关于它的证明了. 在平时的做题中,我们会遇到这样的区间dp问题 它的状态转移方程形式一般为dp[i][j]=min(dp[i][k]+dp[k+1] ...

  4. 『一维线性dp的四边形不等式优化』

    四边形不等式 定义:设\(w(x,y)\)是定义在整数集合上的的二元函数,若对于定义域上的任意整数\(a,b,c,d\),在满足\(a\leq b\leq c \leq d\)时,都有\(w(a,d) ...

  5. BZOJ1563/洛谷P1912 诗人小G 【四边形不等式优化dp】

    题目链接 洛谷P1912[原题,需输出方案] BZOJ1563[无SPJ,只需输出结果] 题解 四边形不等式 什么是四边形不等式? 一个定义域在整数上的函数\(val(i,j)\),满足对\(\for ...

  6. hdu 2829 Lawrence(四边形不等式优化dp)

    T. E. Lawrence was a controversial figure during World War I. He was a British officer who served in ...

  7. HDU 2829 区间DP & 前缀和优化 & 四边形不等式优化

    HDU 2829 区间DP & 前缀和优化 & 四边形不等式优化 n个节点n-1条线性边,炸掉M条边也就是分为m+1个区间 问你各个区间的总策略值最少的炸法 就题目本身而言,中规中矩的 ...

  8. 区间DP石子合并问题 & 四边形不等式优化

    入门区间DP,第一个问题就是线性的规模小的石子合并问题 dp数组的含义是第i堆到第j堆进行合并的最优值 就是说dp[i][j]可以由dp[i][k]和dp[k+1][j]转移过来 状态转移方程 dp[ ...

  9. 四边形不等式优化DP——石子合并问题 学习笔记

    好方啊马上就要区域赛了连DP都不会QAQ 毛子青<动态规划算法的优化技巧>论文里面提到了一类问题:石子合并. n堆石子.现要将石子有次序地合并成一堆.规定每次只能选相邻的2堆石子合并成新的 ...

随机推荐

  1. HandlerSocket ---MySQL与NoSQL ---SQL与NoSQL的融合(转)

    项目地址:https://github.com/ahiguti/HandlerSocket-Plugin-for-MySQL 写这一篇内容的原因是MySQL5.6.2突然推出了memcached的功能 ...

  2. [LeetCode] 139 Word Break(BFS统计层数的方法)

    原题地址: https://leetcode.com/problems/word-break/description/ 题目: Given a non-empty string s and a dic ...

  3. GIT使用—创建一个版本库

    一.GIT命令行 [root@localhost ~]# git usage: git [--version] [--exec-path[=GIT_EXEC_PATH]] [--html-path] ...

  4. Saltstack 命令行:批量覆盖指定文件

    master指定文件,覆盖到所有minion命令 salt-cp '*' /etc/hosts /etc/ -------------------------------------------- { ...

  5. 深入解析Koa之核心原理

    这篇文章主要介绍了玩转Koa之核心原理分析,本文从封装创建应用程序函数.扩展res和req.中间件实现原理.异常处理的等这几个方面来介绍,写的十分的全面细致,具有一定的参考价值,对此有需要的朋友可以参 ...

  6. 基于Bootstrap的jQuery登录表单

    在线演示 本地下载

  7. java实现同步的方法

    为何要实现同步 java允许多线程并发控制,当多个线程同时操作一个可共享的资源变量时(如数据的增删改查),      将会导致数据不准确,相互之间产生冲突,因此加入同步锁以避免在该线程没有完成操作之前 ...

  8. jQ&js给label

    <strong>当前角色:</strong><label id="lblRoleName" style="margin-bottom: 0p ...

  9. linux top ps 命令

    http://javawind.net/p131 VIRT:virtual memory usage 虚拟内存1.进程“需要的”虚拟内存大小,包括进程使用的库.代码.数据等2.假如进程申请100m的内 ...

  10. ExtJS Ext.Ajax.request最好设为同步

    ExtJS 中Ext.Ajax.request最好设为同步,即async: false,因为如果Ajax后面需要用到Ajax更新的数据的话,设置同步,后面才能用到最新的数据. function Get ...