\ (1 \) digital triangle
Every time the lower left or lower right can go a grid, seeking the path of maximum weight.
\ (d (i, j) = max (d (i + 1, j), d (i + 1, j + 1)) + a (i, j). \) boundary is \ (d (n + 1 , J) = 0 \) , pushed from the bottom up (because to ensure \ (i + 1 \) line section \ (I \) before the update OK)
for(int i=1;i<=n+1;++i) d[n+1][i]=0;
for(int i=n;i>=1;--i)
{
for(int j=1;j<=i;++j)
{
d[i][j]=max(d[i+1][j],d[i+1][j+1])+a[i][j];
}
}
\ (2 \) nested rectangles
There \ (n-\) rectangles, each rectangle with a tuple \ ((a, b) \ ) FIG. We predetermined rectangular \ (X (a, b) \) can be nested in the rectangle \ (Y (c, d) \) if and only if \ (A <C, B <D \) , or \ (b < C, a <D \) (rotated \ (90 \) degrees). Selecting as many rectangle aligned so that except the last one, can be nested within each rectangle a lower rectangle. If multiple solutions, as small as possible to ensure the lexicographical
\ (DAG \) longest road problem
//dp[i]表示的是从i点出发的最长路
int dp(int x)
{
int &ans=d[x];
if(ans) return ans;
for(int i=1;i<=n;++i)
{
if(G[x][i])
{
ans=max(ans,dp(i)+1);//注意记录的是从终点到起点的距离,这是为了方便字典序最小方案的输出
}
}
d[x]=ans;
return ans;
}
void print(int i)
{
printf("%d ",i);
for(int j=1;j<=n;++j)
{
if(G[i][j]&&d[j]+1==d[i])
{
print(j);
}
}
}
for(int i=1;i<=n;++i)
{
scanf("%d%d",&a[i],&b[i]);
if(a[i]>b[i]) swap(a[i],b[i]);
}
for(int i=1;i<=n;++i)
{
for(int j=1;j<=n;++j)
{
if(a[i]>a[j]&b[i]>b[j])
{
G[j][i]=1;
}
}
}
int Max=0;
int endpos;
for(int i=1;i<=n;++i)
{
if(dp(i)>Max)
{
Max=dp[i];
endpos=i;
}
}
print(endpos);
\ (3 \) coin issue
\ [F (i) = min (inf, f [i-Vi] +1 | Vi <= i), g (i) = max (-inf, g [i-Vi] +1 | Vi <= i) (Vi coin denominations) \]
\ (4.01 \) backpack has a special topic explain in detail
\ (5 \) point set matching problems (like pressure \ (DP \) )
\ (d (S) \) represents a set of \ (S \) shortest distance after pairing
double dis(int i,int j)
{
return sqrt((a[i].x-a[j].x)*(a[i].x-a[j].x)+(a[i].y-a[j].y)*(a[i].y-a[j].y));
}
int main()
{
int n;
scanf("%d",&n);
for(int i=0;i<n;++i) scanf("%d%d",&a[i].x,&a[i].y);
memset(d,0x7f,sizeof(d));
d[0]=0;
for(int i=1;i<(1<<n);++i)//由于第一个点无论如何都是要配对的,所以无需枚举(否则时间复杂度会
{ //乘上一个n)
int k=0;
while(!(i&(1<<k))) ++k;
for(int j=k+1;j<n;++j)
{
if(i&(1<<j)) d[i]=min(d[i],d[i^(1<<k)^(1<<j)]+dis(k,j));
}
}
}
\ (6 \) longest subsequence problem rises \ ((the LIS) \)
Primary: \ (O (the n-^ 2) \) (but not too good, and I learned the second, they never used it)
Advanced: \ (O (nlogn) \) \ (D [I] \) represented by \ (a [i] \) length of the longest sub-sequences of the rising end
for(int i=1;i<=n;+i) g[i]=inf;
for(int i=0;i<n;++i)
{
int k=lower_bound(g+1,g+n+1,a[i])-g;
d[i]=k;
g[k]=a[i];
}
\ (7 \) the longest common subsequence problem \ ((the LCS) \) [Note: \ (the LCS \) sometimes referred to as the longest common suffix, and \ (the LCP \) longest common prefix correspond]
for(int i=0;i<la;++i)
{
for(int j=0;j<lb;++j)
{
if(a[i]==b[j])
{
d[i][j]=max(d[i][j],d[i-1][j-1]+1);
}
else if(a[i]!=b[j])
{
d[i][j]=max(d[i-1][j],d[i][j-1]);
}
}
}
You can also scroll through an array optimization
int f=0;
for(int i=0;i<la;++i)
{
f^=1;
for(int j=0;j<lb;++j)
{
if(a[i]==b[j])
{
d[f][j]=max(d[f][j],[f^1][j-1]+1);
}
else if(a[i]!=b[j])
{
d[f][j]=max(d[f^1][j],d[f][j-1]);
}
}
}
\ (8 \) maximum continuous and
Prefix and practices:
for(int i=1;i<=n;++i)
{
scanf("%d",&a[i]);
sum[i]=sum[i-1]+a[i];
}
int Maxn=sum[n],Max=0;
for(int i=n-1;i>=1;--i)
{
Max=max(Max,Maxn-sum[i]);
Maxn=max(Maxn,sum[i]);
}
Dynamic programming practices: \ (D [i] \) represents the maximum continuous ending and i
for(int i=1;i<=n;++i) scanf("%d",&a[i]);
for(int i=1;i<=n;++i)
{
d[i]=max(0,d[i-1])+a[i];
}