[열정] 부정 공황 Jizhong --Day2. 느낌

솔직히 말해서, 오늘의 질문은 정말 간단합니다.

하지만 ......

50/0/0/100.

그 후, 프로그램을 살펴, 나는 바보 같은 실수를 발견했다. . . 정말 열심히 qwq 아니라, 그 질문이 작성하지 않은


 

1. 요리 :

기술

  음식, 음식은 좋은 원료를 선택하는 가장 중요한 의미를 아주 맛있는 요리입니다.
  신맛 S B 쓴맛 두 특성 모두 각 성분의 N 종류가 있는데, 다양한 재료, 각 성분의 제품의 각 성분의 쓴 맛 쓴맛의 총 정도의 산성도 총 산도를 선택할 때 와.
  아시다시피, 원료로도 음식도 쓴 산, 총 산도 및 최소 절대 차이의 합계 고통을 선택했는지 확인합니다.
  음식은 물이 아니다, 그래서 당신은 적어도 하나 개의 식사를 선택해야하기 때문에.
 

입력

  첫 번째 행의 입력을 정수 N (1 <= N <= 10)이 포함되어, 원료의 종류의 수를 나타낸다.
  다음 N 라인은 신맛 쓴맛의 각각의 공간에 의해 분리 된 두 개의 정수를 포함한다.
  입력 데이터는 모든 원료가 선택되는 총 산도 더 이상 9 ^ 10 이상의 합계 통증을 보장하는 경우.

산출

  총 산도 쓴 총 출력 사이의 최소 차이.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

이 질문은 폭풍입니다! 검색! 하지만 결과는 국경 간 거래로, 데이터의 마지막 세트에 있었을 것이다, 시작 포인트를 잃었다 ......

1 #INCLUDE <. 비트 / stdc ++ H>
 2  사용  스페이스 성병;
3  INT N;
4  INT A [ 12 ], C [ 12 ] = 위협 1E9, ANS [ 1000 ], 예를 들어 [ 1000 ] 탄소 나노 튜브;
5  공극 DFS ( INT의 H, INT MUL INT 오전 INT의 태그) {
 (6)      의 경우 (I> n)의 리턴 ;
7      ANS [CNT ++ = 분 (위협 그것 (MUL I));
8      예 [컷 = 태그;
9      DFS (K + 1 , MUL * A [K +1 , 합계 + B [K + 1 ], 1 );
10      DFS (K + 1 , MUL, 합계 태그);
11  }
 12  INT 의 main () {
 13      는 scanf ( " %의 D ' , N);
14      INT oans = 1E9;
(15)      에 대한이 ( int로 I = 1 난 ++; i가 N = < {)
 16          (scanf와 " % d 개 %의 D를 " & A [I], B [I]);
17          oans = 분 (oans, ABS (a [I] - B [I]));
18      } 
 19      DFS (0 , 1 , 0 , 0 );
(20)      에 대한이 ( int로 I = 1 ; i가 CNT를 <=, 내가 ++ ) {
 21 일          경우 (Tg가이 [I]!) 계속 ;
22 일          경우 (ANS [I] <oans)의 oans = 된 ANS [I];
23      }
 24      의 printf ( " % D \ 없음 " , oans);
25      반환  0 ;
26 }

2. 몇 게임을 가지고

기술

  앨리스는 "위대한 탕산 지진"를 참조 동행 밥을 원하지만 밥은 매우 감정적 인 사람이기 때문에, 눈물이 두려워하지 않는다, 그러나 나는 그가 게임을 제안 거부 이유로이 죄송합니다.
  다음과 같이 N 양의 정수 원, 규칙은 다음과 같습니다
  두 선수가 가져 오는 돌아가며 •;
  의인 플레이어가 임의의 숫자 X를 취할 수 있습니다 얻을 시작 •;
  현재 플레이어의 시작은 두 번째 단계에서 X를 취할 수 있습니다 • (플레이어가 단지를 취할 번호) 왼쪽과 인접한 숫자의 우측;
  ; • 모든 숫자까지 완료 가지고, 게임은 끝났어
  • 승리의 더 홀수를 얻을.
  밥은 관대함을 보여주기 위해, 앨리스가 처음 보자,하지만 그는 자신과 앨리스 앨리스는 이제 그에게 마지막 승리를 만드는 첫 번째 단계를 에뮬레이트 얼마나 많은 계산 도움을 요청, 아주 똑똑한 사람들 잊어 버렸습니다.
 

입력

  첫 번째 행은 정수 N (1 <= N은 <= 100), 그 값의 수를 나타냄을 포함한다. 두 번째 행은 N 양의 정수 1 내지 1000 사이의 각각의 개수가 서로 다른 두 숫자를 포함한다.

산출

  출력 앨리스의 첫 번째 단계는 얼마나 많은 에뮬레이트.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

먼저 번호를 제거 할 때이 질문은 매우 미묘하다, 수치의 나머지 시퀀스로 확장 할 수 있습니다 양쪽에서 가져온 각 시퀀스, 그것은 간격 DP된다.

모두가 천재 DP 게임 이론의 문제에 대한 최적의 솔루션으로 촬영, 설정하는 것이 좋습니다.

집합 S [I] [j]가 홀수 간격의 개수를 나타내며, F [I] [j]가 I 또는 J가 수득 될 수있는 최대 홀수 복용 우세를 나타내고,

F [I] [J] = 최대 (S [I] [J] -f [I + 1] [J], S [I] [J] -f [I] [J-1), 이송 방향 밖으로의 내부와 접두사 최적화.

 

#include<bits/stdc++.h>
using namespace std;
const int N=110;
int n;
int a[N*2];
int s[N*2];
int f[N][N],ans;
int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i]);
        a[i]&=1;
    }
    for(int i=1;i<=n;i++){
        memset(f,0,sizeof(f));
        memset(s,0,sizeof(s));
        for(int j=1;j<=n;j++){
            s[j]=s[j-1]+a[j];
            f[j][j]=a[j];
        }
//        for(int i=1;i<n;i++){
//            for(int j=1;j+i<=n;j++){
//                f[i][i+j]=max(s[i+j]-s[j-1]-f[j+1][i+j],s[i+j]-s[j-1]-f[j][i+j-1]);
//            }
//        }
        for(int k=1;k<=n-2;k++) { 
            for(int j=1;j+k<=n;j++) { 
                int l=k+j; 
                f[j][l]=max(s[l]-s[j-1]-f[j+1][l],s[l]-s[j-1]-f[j][l-1]); 
            } 
        } //
        f[1][n]=s[n]-f[2][n];
        if(s[n]/2+1<=f[1][n]) ans++;
        for(int i=0;i<=n;i++) a[i]=a[i+1];
        a[n]=a[0];
    }
    printf("%d\n",ans);
//    for(int i=1;i<=n;i++){
//        for(int j=1;j+i<=n*2;j++){
//            f[j][j+i-1]=max(s[j+i]-s[j-1]-f[j+1][j+i-1],s[j+i]-s[j-1]-f[j][j+i-2]);
//        }
//    }
//    for(int i=1;i<n;i++){
//        for(int j=1;j+i<=n*2;j++){//l=j,r=j+i
//            f[j][j+i]=max(s[j+i]-s[j-1]-f[j+1][j+i],s[j+i]-s[j-1]-f[j][j+i-1]); 
//        }
//    }
//    for(int k = 1;k <= n - 2;k++) { 
//            for(int j = 1;j <= 2*n - k;j++) { 
//                int l = k + j; 
//                f[j][l]=max(s[l]-s[j-1]-f[j+1][l],s[l]-s[j-1]-f[j][l-1]); 
//            } 
//    } 
//    for(int i=1;i<=2*n;i++){
//        cout<<a[i]<<" ";
//    }
//    for(int i=1;i<=2*n;i++){
//        cout<<s[i]<<" ";
//    }
//    for(int i=1;i<=n;i++){
//        if(s[i+n-1]-s[i-1]-f[i+1][i+n-1]>(n>>1)) ans++;
//    }
//    printf("%d",ans);
    
    return 0;
}

 

唯一一道不水的题目。

 

 

 

 


 

3.删除

  这是道水题……但是当时没想到。

Description

  Alice上化学课时又分心了,他首先画了一个3行N列的表格,然后把数字1到N填入表格的第一行,保证每个数只出现一次,另外两行他也填入数字1到N,但不限制每个数字的出现次数。
  Alice现在想删除若干列使得每一行排完序后完全一样,编程计算最少需要删除多少列。
 

Input

  第一行包含一个整数N(1<=N<=100000),表示表格的列数。
  接下来三行每行包含N个整数,每个数在1到N之间,而且第一行的数互不相同。

Output

  输出最少需要删除的列数。

 

 

 

 

 

 

 

 

  首先,对于一个表格,第二行和第三行不一定是全排列,就说明一定会有缺少的数字,我们用count记录一下。

  不断遍历1~n,找到第一行有而第二行or第三行没有的数字,最重要的是把第一行的对应数字归零(这样就不会判断到它),然后对应得一列删除。

  设置一个flag,判断每次删除情况,未删则跳出。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int N=1e5+10;
 4 int n;
 5 int ct1[N],ct2[N],ct3[N];
 6 int t2[N],t3[N],ans;
 7 int main(){
 8     scanf("%d",&n);
 9     for(int i=1;i<=n;i++){
10         scanf("%d",&ct1[i]);
11     }
12     for(int i=1;i<=n;i++){
13         scanf("%d",&ct2[i]);
14         t2[ct2[i]]++;
15     }
16     for(int i=1;i<=n;i++){
17         scanf("%d",&ct3[i]);
18         t3[ct3[i]]++;
19     }
20     bool flag=false;
21     while(!flag){
22         flag=true;
23         for(int i=1;i<=n;i++){
24             if(ct1[i]&&!(t2[ct1[i]]&&t3[ct1[i]])){
25                 flag=false;
26                 ct1[i]=0;
27                 ans++;
28                 t2[ct2[i]]--;
29                 t3[ct3[i]]--;
30             }
31         }
32     }
33     printf("%d",ans);
34     return 0;
35 }

4.区间

Description

  Alice收到一些很特别的生日礼物:区间。即使很无聊,Alice还是能想出关于区间的很多游戏,其中一个是,Alice从中选出最长的不同区间的序列,其中满足每个区间必须在礼物中,另序列中每个区间必须包含下一个区间。
  编程计算最长序列的长度。
 

Input

  输入文件第一行包含一个整数N(1<=N<=100000),表示区间的个数。
  接下来N行,每行两个整数A和B描述一个区间(1<=A<=B<=1000000)。

Output

  输出满足条件的序列的最大长度。

 

 

 

 

 

 

 

 

 

 

这道题用了一点贪心的思想,我们将右端从大到小排序,这样遍历只用考虑左端点即可。

考虑包含关系,每一个左端点都要比上一个左端点大,所以就是找最长不下降子序列的问题了。

这里复习一下:

  我们用len表示答案长度,或者说答案区间的长度,遍历数组,每测到一个新的值,就与答案数组的len位置比较,如果大于ans[len],则直接令ans[++len]=a[i],即更新答案长度,但是如果小于,则在答案数组中找到一个比这个数大的第一个数与之替换(因为本来也可以绕过那个数到达这个数,且不会影响答案)(这里使用upper_bound,注意返回的是地址,要减去初地址(如果是数组就减去数组名称)),然后没了。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int N=1e6+10;
 4 struct line{
 5     int l,r;
 6 }a[N];
 7 int n,f[N];
 8 bool cmp(line t1,line t2){
 9     if(t1.r==t2.r) return t1.l<t2.l;
10     else return t1.r>t2.r;
11 }
12 int main(){
13     scanf("%d",&n);
14     for(int i=1;i<=n;i++){
15         scanf("%d%d",&a[i].l,&a[i].r);
16     }
17     sort(a+1,a+n+1,cmp);
18     f[1]=a[1].l;
19     int len=1;
20     for(int i=2;i<=n;i++){
21         if(a[i].l>=f[len]) f[++len]=a[i].l;
22         else{
23             int j=upper_bound(f+1,f+len+1,a[i].l)-f;
24             f[j]=a[i].l;
25         }
26     }
27     printf("%d\n",len);
28     return 0;
29 }

总结:还是很菜,明天继续。

추천

출처www.cnblogs.com/Nelson992770019/p/11290892.html