2019.4.18训练

今天的题还是挺不错的:

1:codeforces811c

我先贴一个博客上来:https://blog.csdn.net/westbrook1998/article/details/82929293

感觉这个人的思路和我差不多,可能这种题都差不多的做法把。。。。。。。。。。。。。。。

网上都差不多,直接上代码把,题解在代码里面:

 1 /*
 2      首先这道题它给了你ai的范围是0-5000
 3      然后它告诉了你如果取一个数,就要取全部的数
 4      那么就肯定要处理出全部的段出来,然后接下来的话我们就预处理一下L ,R
 5      然后类似最长上升子序列那样预处理一波就行了
 6      注意一下长度为1的段,我一开始wa了一发
 7 */
 8 #include <iostream>
 9 #include <cstdio>
10 #include <cstring>
11 #include <cmath>
12 #include <algorithm>
13 #include <bitset>
14 typedef long long ll;
15 using namespace std;
16 int dp[5010];
17 int maxdp[5010];
18 int cnt[5010][5010];//合法段的区间异或值
19 int n;
20 int ai[5010];
21 int l[5010];
22 int r[5010];
23 int main(){
24     scanf("%d",&n);
25     for(int i=1;i<=n;i++) scanf("%d",&ai[i]);
26     memset(l,-1,sizeof(l));
27     memset(r,-1,sizeof(r));
28     memset(cnt,-1,sizeof(cnt));
29     dp[0]=0;
30     for(int i=1;i<=n;i++) if(l[ai[i]]==-1) l[ai[i]]=i;
31     for(int i=n;i>=1;i--) if(r[ai[i]]==-1) r[ai[i]]=i;
32     for(int i=1;i<=n;i++){
33         if(l[ai[i]]!=i) continue;
34         int maxx=r[ai[i]];
35         int ans=ai[i];
36         for(int j=i;j<=n;j++){
37             if(l[ai[j]]<i){
38                 break;
39             }
40             if(l[ai[j]]==j&&j!=i){
41                 ans^=ai[j];
42                 maxx=max(maxx,r[ai[j]]);
43             }
44             if(maxx==j) cnt[i][j]=ans;
45         }
46     }
47     int ans=0;
48     for(int i=1;i<=n;i++){
49         for(int j=1;j<=i;j++){
50             if(cnt[j][i]!=-1){
51                 dp[i]=max(dp[i],maxdp[j-1]+cnt[j][i]);
52             }
53         }
54         ans=max(ans,dp[i]);
55         maxdp[i]=max(dp[i],maxdp[i-1]);
56     }
57     //cout<<cnt[3][5]<<endl;
58     printf("%d\n",ans);
59     return 0;
60 }
View Code

2:codeforces630G

首先这个5个黑和3个红是不互相影响的

那么我们只要分别对这个分析一波就行了

然后上上代码

先鸽了下,下次再补

#include <algorithm>
#include <iostream>
#include <cstdio>
#include <cmath>
#include <bitset>
#include <cstring>
typedef long long ll;
using namespace std;
ll n;

ll C(ll a,ll b){
    ll f1=1,f2=1;
    for(ll i=a;i>=a-b+1;i--){
        f1*=i;
    }
    for(ll i=1;i<=b;i++){
        f2*=i;
    }
    return f1/f2;
}

int main(){
    scanf("%lld",&n);
    if(n==1) printf("1\n");
    else if(n==2) printf("24\n");
    else if(n==3){
        printf("210\n");
    }else if(n==4){
        printf("1120\n");
    }else {
        ll ans1=C(n,3)+C(n,1)+C(n,1)*C(n-1,1);
        //ll ans2=C(n,5)+C(n,1)*C(n-1,1)+C(n,1)+C(n,1)*C(n-1,1)+C(n,1)*C(n-1,2)+C(n,1)*C(n-1,2);
        ll ans2=C(n,5)+4*C(n,4)+6*C(n,3)+4*C(n,2)+C(n,1);
        // 1个       4个          5个         3个            3个             2个
        cout<<ans1*ans2<<endl;
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/pandaking/p/10674431.html