QBXT DAY1

1.枚举
2.前缀和维护 差值维护(详见上一篇)
3.最大字段和

for (i=1; i<=n; i++)
{
    sum+=a[i];
    if (sum<0) sum=0;
    ans=max(ans,sum);
}

下见应用

圈地运动(化面为线)求最大子区间和
for (i=1; i<=n; i++)
  for (j=1; j<=n; j++)
    s[i][j]=s[i-1][j]+a[i][j];
for (i=1; i<=n; i++)
  for (j=i; j<=n; j++)
  {
    for (k=1; k<=n; k++) 
      b[k]=s[j][k]-s[i-1][k];
    ans=max(ans,work());//work()是求最大子段和,b的(化为一维)
  }

4.不易出错的二分

//二分
//k a从小到大排好序了
L=1; R=n; mid=(L+R)/2;
while (L<=R)
{
    if (a[mid]<=k) 
    {L=mid+1; mid=(L+R)/2;} 
        else
    {R=mid-1; mid=(L+R)/2;}
}
cout<<R<<endl;
//最终 L=R+1

5.two point
a,b 数组,从中各取一个数,使其和最大但小于k

//、、two point!!两子针
t=n;
for (i=1; i<=n; i++)
{
    while (a[i]+b[t]>p) t--;
    ans=max(ans,a[i]+b[t]); 
}

6.折半搜索 (这个我也不会)直接贴标程

、、、、折半搜索+two point
体积之和<=m
价值之和最大
给两部分体积之和都排个序
m=10
5 100 100 
5 100 100

4 5 6
3 3 4

n
w[i],c[i]

mid=n/2;
1~mid  mid+1~n

void dfs(int x,int X,int y,int z)
{
    if (x==X+1)
    {
        a[++cnta].x=y;
        a[cnta].y=z;
        return;
    }
    dfs(x+1,X,y+w[x],z+c[x]);
    dfs(x+1,X,y,z);
}
void dfs2(int x,int X,int y,int z)
{
    if (x==X+1)
    {
        b[++cntb].x=y;
        b[cntb].y=z;
        return;
    }
    dfs2(x+1,X,y+w[x],z+c[x]);
    dfs2(x+1,X,y,z);
}       
dfs(1,mid,0,0);
dfs2(mid+1,n,0,0);
将a和b按照.x从小到大排序。
for (i=1; i<=cnta; i++) 
a[i].y=max(a[i-1].y,a[i].y);
for (i=1; i<=cntb; i++) 
b[i].y=max(b[i-1].y,b[i].y);
t=cntb;
for (i=1; i<=cnta; i++)
{
    while (a[i].x+b[t].x>m) t--;
    if (t) 
          ans=max(ans,a[i].y+b[t].y);
}
meet in the middle 
折半搜索(meet in the middle)    上面!
n<=40  2^(n/2)  2^(n/2)*n  n^4  n^5
n<=35  2^(n/2)*n  2^(n/2)*n^2  n^5  n^6

7.贪心
8.压位

压位(一般压为10^410^9)
详见下一篇
补5printf("%05d",a[i]);

9.待写 K’th number hard

10.快速幂
数组版(x进制)

二进制

while (b) {c[++cnt]=b%2; b/=2;}
d[1]=a;
for (i=2; i<=cnt; i++) d[i]=d[i-1]*d[i-1];
ans=1;
for (i=1; i<=cnt; i++) if (c[i]==1)
  ans=ans*d[i];

进制

    s=a;
    while(k>1)
    {
        if(k%2==1)
        ans=ans*s;
        s=s*s;
        k=k/2;
    }
    ans=s*ans;

递归版

11.贪心

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值