$ NOIp 제목을 수행하는 인기 녹화 그룹을 $

\ ([NOIp2014] \) 나선형 행렬

\(솔\)

직접 시뮬레이션, 또는 전체 행되면 전체 열을. 복잡성 \을 (O (N-) \) .

\(암호\)

#include<bits/stdc++.h>
#define il inline
#define Ri register int
#define go(i,a,b) for(Ri i=a;i<=b;++i)
#define yes(i,a,b) for(Ri i=a;i>=b;--i)
#define e(i,u) for(Ri i=b[u];i;i=a[i].nt)
#define mem(a,b) memset(a,b,sizeof(a))
#define ll long long
#define db double
#define inf 2147483647
using namespace std;
il int read()
{
    Ri x=0,y=1;char c=getchar();
    while(c<'0'||c>'9'){if(c=='-')y=-1;c=getchar();}
    while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+c-'0';c=getchar();}
    return x*y;
}
int n,s,x,z,y,nx,ny,tx,ty,nd,ex,ey,nw;
il bool ck()
{
    Ri x1=nx,x2=tx,y1=ny,y2=ty;
    if(x1>x2)swap(x1,x2);if(y1>y2)swap(y1,y2);
    return (ex>=x1 && ex<=x2 && ey>=y1 && ey<=y2);
}
il int calc(){return abs(nx-ex)+abs(ny-ey);}
int main()
{
    n=read(),ex=read(),ey=read();
    if(ex==1 && ey==1){printf("1\n");return 0;}
    nx=ny=nd=1;nw=1;
    while(nd<=n*n)
    {
        if(nw==1){tx=nx,ty=n-y;++s;}
        if(nw==2){tx=n-x,ty=ny;++y;}
        if(nw==3){tx=nx,ty=z+1;++x;}
        if(nw==4){tx=s+1,ty=ny;++z;}
        if(ck()){printf("%d\n",nd+calc());break;}
        nd+=abs(nx-tx)+abs(ny-ty);nx=tx,ny=ty;++nw;if(nw>4)nw=1;
    }
    return 0;
}
    

\ ([NOIp2014] \) 부분 행렬

\(솔\)

간단한 검색을 얻을 수 있습니다 \ (80pts \) . 검색 최적화를 생각하는 것은 매우 아니다 (사실, 나는 거의 것) 때문에이 문제가 직접 할 수있는 메모리를 검색합니다. 특히, 첫 번째 행이 선택 될 검색 아웃 한 다음 열을 선택하고 검색 할 때 라인의 메모리.

\ (UPD가 : \) . 때 검색 라인은 열의 메모리의 메모리 것으로 보인다 그러나이 문제의 정도를 발견했다.

\(암호\)

#include<bits/stdc++.h>
#define il inline
#define Ri register int
#define go(i,a,b) for(Ri i=a;i<=b;++i)
#define yes(i,a,b) for(Ri i=a;i>=b;--i)
#define e(i,u) for(Ri i=b[u];i;i=a[i].nt)
#define mem(a,b) memset(a,b,sizeof(a))
#define ll long long
#define db double
#define inf 2100000000
using namespace std;
il int read()
{
    Ri x=0,y=1;char c=getchar();
    while(c<'0'||c>'9'){if(c=='-')y=-1;c=getchar();}
    while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+c-'0';c=getchar();}
    return x*y;
}
const int N=20;
int n,m,r,c,a[N][N],b[N],d[N],as=inf,ct,f[20][20];
il void init(){mem(f,-1);}
il int dfs2(Ri nw,Ri lst,Ri sum)
{
    if(nw>r)return 0;
    Ri ret=inf;
    if(f[nw][lst]!=-1)return f[nw][lst];
    go(i,lst+1,n-r+nw)
    {
        d[nw]=i;Ri tmp=0;bool fl=1;
        go(j,2,c){tmp+=abs(a[i][b[j]]-a[i][b[j-1]]);if(tmp>=as){fl=0;break;}}
        if(!fl)continue;
        if(nw!=1)go(j,1,c){tmp+=abs(a[i][b[j]]-a[d[nw-1]][b[j]]);if(tmp>=as){fl=0;break;}}
        if(!fl)continue;
        ret=min(ret,dfs2(nw+1,i,tmp)+tmp);
    }
    return f[nw][lst]=ret;
}
il void dfs1(Ri nw,Ri lst)
{
    if(nw>c){init();as=min(dfs2(1,0,0),as);return;}
    go(i,lst+1,m-c+nw)
        b[nw]=i;dfs1(nw+1,i);
}
int main()
{
    n=read(),m=read(),r=read(),c=read();
    go(i,1,n)go(j,1,m)a[i][j]=read();
    dfs1(1,0);
    printf("%d\n",as);
    return 0;   
}

\ ([NOIp2015] \) 세일즈

\(솔\)

더 직접적인 아이디어는 각 질문입니다 이렇게 (당신은 무엇과 트리 라인을 유지할 수) 간 먼 위치 및 기타 직접 선거를 열거 .... 복잡성은 약 N (\ (O 2logn ^) \) 얻기 \ (60pts \) 하지 문제.

첫번째 직접 선택이 고려 \ (A_I \) 앞에 \ (X \) 시도 먼저 큰 라운딩을하고. \ (X는 \)\이 (A_I는 \) 추가 옵션 세트를 선택할 수 있습니다. \ (A_I \를 ) 앞에 \ (X \) 큰 기여를한다 SUM \ (\ A + D * 2 \) , 그리고 지금 당신이 버려야 할 \ (X의 \)를 교환 \합니다 (y 축 \) , 다음 그래서 높이기 위해 공헌 할 수 않습니다 \ ((D_y를 -D) * 2 A_x + a_y \) . 사실 간단하게 선택할 수있는 가장 큰 기여 중 하나를 선택합니다 \ (D_y * 2 + a_y \ ) 는 배열의 직접 사용을 유지할 수 있도록 최대가 될 수 있습니다.

\(암호\)

#include<bits/stdc++.h>
#define il inline
#define Ri register int
#define go(i,a,b) for(Ri i=a;i<=b;++i)
#define yes(i,a,b) for(Ri i=a;i>=b;--i)
#define e(i,u) for(Ri i=b[u];i;i=a[i].nt)
#define mem(a,b) memset(a,b,sizeof(a))
#define ll long long
#define db double
#define inf 2147483647
using namespace std;
il int read()
{
    Ri x=0,y=1;char c=getchar();
    while(c<'0'||c>'9'){if(c=='-')y=-1;c=getchar();}
    while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+c-'0';c=getchar();}
    return x*y;
}
const int N=100010;
int n,ct,sa[N],maxd[N],maxf[N];
struct nd{int a,d;}t[N];
il bool cmp1(nd x,nd y){return x.d<y.d;}
il bool cmp(nd x,nd y){return x.a>y.a;}
int main()
{
    n=read();
    go(i,1,n)t[i].d=read();
    go(i,1,n)t[i].a=read();
    sort(t+1,t+n+1,cmp);
    go(i,1,n)if(t[i].a==0){n=i-1;break;}
    go(i,1,n)sa[i]=sa[i-1]+t[i].a,maxd[i]=max(maxd[i-1],t[i].d);
    yes(i,n,1)maxf[i]=max(maxf[i+1],t[i].d*2+t[i].a);
    go(i,1,n)printf("%lld\n",max(sa[i]+maxd[i]*2,sa[i-1]+maxf[i+1]));
    return 0;
}

\ ([NOIp2015] \) 합산

\(솔\)

문제를 단순화하기위한 것이다 테이프는 점수 : \ (\ sum_ = 0 (1) (I는 J를 +) (num_i의 num_j의 +) {I는 J (JI) \ &를 <} \.) .

같은 색의 직접 열거 \ (I, J \) , \ (점검 \ (JI) \) 축적도, 당신이 얻을 수있는 대답 여부를 \ (80pts \) . 생략하면 \을 (체크 () \) 이 단계 잘. 실제로, 패리티에 의한로는, 응답에 기여를 생성 할 수있는 것과 동일한 알킬기, 동색으로 그룹화 될 수있다.

가정 \ ([L, R] \ ) 간격 컬러 누적 응답이다 :

\ (\ sum_ I = {L} ^ {R} \ {_ 합계 = J + i가 1} ^ RN (나는 J +) (+ num_i num_j) \)

\ (= \ sum_ {I} = 1 * ^ RI num_i * (RL-1) + \ sum_ I = {L} ^ {R} \ 합 _ {I} J = ^ RI num_j * \)

\ (= \ sum_ {I} = 1 * ^ RI num_i * (RL-1) + \ sum_ I = {L} ^ {R} I * \ {sum_ I = 1} ^ RN num_i \)

그 일본어 문장 참고 \ (L = 연구 \) 조건을.

\(암호\)

#include<bits/stdc++.h>
#define il inline
#define Ri register int
#define go(i,a,b) for(Ri i=a;i<=b;++i)
#define ll long long    if(ct>1)as+=1LL*s3*(ct-2)%mod+1LL*s1*s2%mod;as%=mod;s1=s2=s3=ct=0;

using namespace std;
il int read()
{
    Ri x=0,y=1;char c=getchar();
    while(c<'0'||c>'9'){if(c=='-')y=-1;c=getchar();}
    while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+c-'0';c=getchar();}
    return x*y;
}
const int N=100010,mod=10007;
int n,m,as,n1,n2;
struct nd{int num,col,pos;}a[N],b[N];
il bool cmp(nd x,nd y){return x.col<y.col;}
int main()
{
    freopen("1.in","r",stdin);
    n=read(),m=read();
    go(i,1,n)if(i&1)a[++n1].num=read(),a[n1].pos=i;else b[++n2].num=read(),b[n2].pos=i;
    n1=n2=0;
    go(i,1,n)if(i&1)a[++n1].col=read();else b[++n2].col=read();
    sort(a+1,a+n1+1,cmp);sort(b+1,b+n2+1,cmp);
    Ri s1=0,s2=0,s3=0,ct=0;
    go(i,1,n1)
    {
    s1+=a[i].num,s2+=a[i].pos,s3+=1LL*a[i].num*a[i].pos%mod,++ct;
    s1%=mod,s2%=mod,s3%=mod;
    if(a[i].col==a[i+1].col)continue;
    if(ct>1)as+=1LL*s3*(ct-2)%mod+1LL*s1*s2%mod;as%=mod;s1=s2=s3=ct=0;
    }
    s1=s2=s3=ct=0;
    go(i,1,n2)
    {
    s1+=b[i].num,s2+=b[i].pos,s3+=1LL*b[i].num*b[i].pos%mod,++ct;
    s1%=mod,s2%=mod,s3%=mod;
    if(b[i].col==b[i+1].col)continue;
    if(ct>1)as+=1LL*s3*(ct-2)%mod+1LL*s1*s2%mod;as%=mod;s1=s2=s3=ct=0;
    }
    printf("%d\n",as);
    return 0;
}

\ ([NOIp2016] \) 항구

\(솔\)

큐가 끝으로 현재 시간을 절약 열고 \ (24 \) (시간 및 국제 포함) 관광객 시간 내에 도착. 어레이 \을 (S [I]는 \) 중국어 국적의 현재 큐 것을 나타낸다 \ (나는 \) 방문자 얼마나 많은 변수 \ (NW \) 시간이 입력이 온라인으로 수행 할 수 있도록 증가하고 있기 때문에 다른 국적의 관광객의 레코드 번호가 필요 오프라인으로 할 수 없습니다, 현재 큐에 있습니다. 때마다 새로운 보트 팀이 처음으로 넣어 방문자가 아래 방향 유지하여 불법 제거하는 \ (S [I]는 \) , 존재하는 경우 ([I]가 \ S) \ 이와된다 (0 \) \ 다음과 \ (- NW \) 후. 꼬리 보트 관광객에 가입 S의 $의 유지 보수 [I] \ (\ 경우) S [내가] $ 그러므로하게는 (1 \) \ , 그래서 (++ NW \) \ . 지난 직접 출력 \ (NW \)는 다음에 다음 사이클을 입력합니다.

\(암호\)

#include<bits/stdc++.h>
#define il inline
#define Ri register int
#define go(i,a,b) for(Ri i=a;i<=b;++i)
using namespace std;
il int read()
{
    Ri x=0,y=1;char c=getchar();
    while(c<'0'||c>'9'){if(c=='-')y=-1;c=getchar();}
    while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+c-'0';c=getchar();}
    return x*y;
}
const int N=100010;
int n,ct,q[N*3],l=1,r,s[N*3],nw;
struct nd{int t,k;}a[N*3];
int main()
{
    n=read();
    go(i,1,n)
    {
    Ri t=read(),k=read();
    go(i,1,k)
    {
        Ri kk=read();
        a[++ct]=(nd){t,kk};q[++r]=ct;
        ++s[kk];if(s[kk]==1)++nw;
    }
    while(a[q[l]].t<=t-86400){if(!(--s[a[q[l]].k]))--nw;++l;}
    printf("%d\n",nw);
    }
    return 0;
}

\ ([NOIp2017] \) 보드

$ 솔 $

매우 검색 질문 상태를 기록해야 할 것 같은데 : 현재있는 그리드는, 얼마를 지출했는지 금, 현재도 얻을 수 있습니다 검색 할 수있는 가지 치기하지 않고, 그래서 그리드를 여행 매직 마커를 사용할 수 있습니다. \ ( 55 부 \) 좋은 결과.

플러스 멀티 최적의 가지 치기는 당신이 얻을 수 있습니다 (\ 10 점)를 \ .

A를 지칭 \ ([I] REM은 [j는 ] \) 나타내는 \ ((1,1) \) 하는 \ ((I, J) \ ) 비용보다 클 때, 우리는 여기 경우 꽃의 최소 비용 포인트 그것은 다음입니다 \ (반환 \) . 뿐만 아니라, 조금이 가지 치기를 기억 않습니다 (마주 \) \을 , 너무 적은 유지 보수 \ (마주 \) 및 속도를 높일 수 있습니다.

\ (UPD \) : 그렇게하고 가격이 원래의 경우보다 커야합니다 경우에만 다음 경우 여기 온,하지만이 반지 한 쌍, 또는 때문에주기가 계속 죽는 경우이 문제가 반드시 동일한 색상이 아닌 경우?

\ (재 UPD \)는 , 위의 사실에 따라, 여기에 연습이지만, 가격이 같거나 시간보다 커야합니다 \ (귀국일 \) 등이 기억 안 \을 (VIS \) .

(당신이 VIS $ 유지하려는 특히 다른 점은 주목할 \ (말을) :하지의 경우 우수한 \) 는 DFS \ (더 나은 다시 ** \ 선고 외출하는) 가 밖으로 DFS $ 판단하기 전에 **.

\(암호\)

#define il inline
#define Ri register int
#define go(i,a,b) for(Ri i=a;i<=b;++i)
#define yes(i,a,b) for(Ri i=a;i>=b;--i)
#define e(i,u) for(Ri i=b[u];i;i=a[i].nt)
#define mem(a,b) memset(a,b,sizeof(a))
#define ll long long
#define db double
#define inf 2147483647
using namespace std;
il int read()
{
    Ri x=0,y=1;char c=getchar();
    while(c<'0'||c>'9'){if(c=='-')y=-1;c=getchar();}
    while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+c-'0';c=getchar();}
    return x*y;
}
const int N=110;
int m,n,col[N][N],dx[4]={1,0,-1,0},dy[4]={0,1,0,-1},as=inf,rem[N][N];
il void dfs(Ri nx,Ri ny,Ri color,Ri sum,bool mag)
{
    if(sum>=as)return;
    if(nx==ny && nx==m){as=min(as,sum);return;}
    rem[nx][ny]=sum;
    go(i,0,3)
    {
        Ri tx=nx+dx[i],ty=ny+dy[i];
            if(tx<1 || tx>m || ty<1 || ty>m)continue;
    if(col[tx][ty])
    {
            if(col[tx][ty]==color && (rem[tx][ty]==-1 || sum<rem[tx][ty]))
            {dfs(tx,ty,col[tx][ty],sum,1);}
            else if(rem[tx][ty]==-1 || sum+1<rem[tx][ty])
            {dfs(tx,ty,col[tx][ty],sum+1,1);}
    }
    else if(mag && (rem[tx][ty]==-1 || sum<rem[tx][ty]))
    {dfs(tx,ty,color,sum+2,0);}
    }
}
int main()
{
    m=read(),n=read();mem(rem,-1);
    go(i,1,n){Ri x=read(),y=read(),c=read();col[x][y]=c+1;}
    dfs(1,1,col[1][1],0,1);
    if(as==inf)as=-1;
    printf("%d\n",as);
    return 0;
}

\ ([NOIp2017] \) 돌 차기

\(솔\)

우선, 용액은 모든 점수까지 추가할지 여부를 결정 \ (케이 \) 비교.

하위 섹션은 적어도 얻을 이동하기 위해 그리드를 검색 할, 검색이 \ (케이 \) 포인트를, 그리고에 대한 답에 대한 통계가. 이것은 얻을 것이다 \을 (20 부 \) .

나는 우리가 할 수 있다고 생각 (dp.jpg의 \)를 \ .

\ ([I] [J F ] \) 표현 전에 \ (나는 \) 격자, 제 1 선택 \ (나는 \) , 그리드 지출 \ (j의 \)를 얻을 수있는 최대 값을 향상시킬 수있다.

\ (F [I] [J] = 최대 (F [K] [g]) + A [i]를, K <I \且\ ABS (X [I] -x [K] -d) <J =且g <= j 개의 \) .

이어서 \ (최대 (F [K] [g]) \) 모노톤 비트 큐 최적화 여기서 사용할 수 있는가?

그러나이 것만으로는 충분하지 않습니다 (AC \) \ 문제, 시간과 공간이 마련되어 있습니다. 우리가 할 수있는 경우 (f를 \)를 \ 일차원 유사한 필요가 없습니다. 정말, 그래서 문제에 대한 해결책을 볼 수 없습니다.

이해 용액 후 : 사실, 상기 \ (DP \) 제 치수가 최소의 비용으로 최소 비용을 열거 대응 명백하게 반 간단 용어이어야에서 : 첫번째 절반 최소 비용을 다음 최소 비용 (\ DP \) , 마지막으로 통계 대답. \ () \ 이상 .

\ (글 \)

자폐증 코드를 작성, 정말 다시 생각하는 코드 크리 딘를 작성 본격적으로 철자해야합니다. 거의 가볍게 코드, 나는 시간 같은 느낌 때마다 직접 오랜 시간 동안 갇혀있을 것이다 작성, 잘못된 어디서나, 실제 시간은 보냈다 훨씬 더. 당신이 닭 요리 아 것을 잊지 마세요! 시원 진정하는 코드를 작성, 천천히.

\(암호\)

#include<bits/stdc++.h>
#define il inline
#define Ri register int
#define go(i,a,b) for(Ri i=a;i<=b;++i)
#define yes(i,a,b) for(Ri i=a;i>=b;--i)
#define e(i,u) for(Ri i=b[u];i;i=a[i].nt)
#define mem(a,b) memset(a,b,sizeof(a))
#define ll long long
#define inf 2147483647
using namespace std;
il int read()
{
    Ri x=0,y=1;char c=getchar();
    while(c<'0'||c>'9'){if(c=='-')y=-1;c=getchar();}
    while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+c-'0';c=getchar();}
    return x*y;
}
const int N=500010;
int n,d,k,x[N],s[N],f[N],as=inf,L,R,mid,q[N];
il bool Ck()
{
    ll sum=0;Ri las=0;
    yes(i,n,1)if(s[i]>0){sum+=s[i];R=max(R,abs(x[i]-x[las]-d));las=i;};
    return (sum>=k);
}
il bool ck(Ri g)
{
    go(i,1,n)f[i]=-inf;f[0]=0;
    Ri l=1,r=0,las=0;
    go(i,1,n)
    {
        while(l<=r && x[q[l]]<x[i]-d-g)l++;
        while(las<=n && x[las]<x[i]-d-g)las++;
        while(las<i && x[las]<=x[i]-d+g )
        {
              if(f[las]==-inf){++las;continue;}
              while(l<=r && f[q[r]]<=f[las])r--;
             q[++r]=las;++las;
        }
        if(l<=r)f[i]=f[q[l]]+s[i];
        if(f[i]>=k)return 1;
    }
    return 0;
}
int main()
{
    n=read(),d=read(),k=read();
    go(i,1,n)x[i]=read(),s[i]=read();
    if(!Ck()){printf("-1\n");return 0;}
    while(L<=R)
    {
        mid=(L+R)>>1;
        if(ck(mid))as=mid,R=mid-1;
    }
    printf("%d\n",as);
    return 0;
}

\ ([NOIp2018] \) 자동차 페리

추천

출처www.cnblogs.com/forward777/p/11664810.html