2021.07.18暑假集训(前缀和+枚举)

1.二维数组的前缀和的表示方法,就是(0,0)点到右下角点的总和

sum[i][j] = mp[i][j] + sum[i - 1][j] + sum[i][j - 1] - sum[i - 1][j - 1];
//某一点的前缀和 = 该点值 + 上面一点的前缀和 + 左边一点的前缀和 - 上边和左边重叠的部分

或者用:

   for(int i=0;i<=5000;i++){
            int s=0;
        for(int j=0;j<=5001;j++){
            s+=a[i][j];
            x[i][j]=s;
        }
    }//每一行的总和
    for(int i=0;i<=5001;i++){
        for(int j=0;j<=5001;j++){
            if(i==0){
                a[i][j]=x[0][j];
            }else{
                a[i][j]=a[i-1][j]+x[i][j];
            }
        }
    }//这一行的总和加上一行的前缀和

说明:

1.一定注意越界的问题,一般限制长度为k的时候最好是从k~n,不要从0-n-k+1

2.奇♂妙拆分 (nowcoder.com)直接暴力枚举即可,不用想太多的什么质因子分解之类的

3.「土」巨石滚滚 (nowcoder.com)解题的时候分了三种情况:

1)bi-ai>0——>这种情况就是增长体力,此时可以很容易的想到先收ai小的,反正都是增长体力

2)bi-ai=0——>这种情况只是比较是不是会出现现在的体力不能够大于ai

3)bi-ai<0——>这种情况,可以用公式推一下,AB可以但是BA不可以的时候,或者说AB体力比BA体力剩余多的情况下是什么,也就是出现了-Aa+Ab-Ba>-Ba+Bb-Aa,此时可以得到必须是bi大的在前面才可以

4.next_permutation的用法

int main(){
    int a[8]={1,2,3,4,5,6,7,8};
    sort(a,a+8);
    do{
        //cout<<a[0]<<" "<<a[1]<<" "<<a[2]<<" "<<a[3]<<endl;
        for(int i=0;i<8;i++)
            cout<<a[i]<<" ";
        cout<<endl;
    }while(next_permutation(a,a+8));

}

 

posted @ 2021-07-18 16:45  bonel  阅读(41)  评论(0编辑  收藏  举报