Educational Codeforces Round 80 D. Minimax Problem

     蒟蒻的jxt人生第一场cf,虽然无比垃圾,场上只A了A(25min),B题(50min)(着实太慢,1A),C题想了半个小时左右一开始以为是排列组合,后来觉得应该是DP但是还是没有头绪第二天写了半天,竟然奇怪的A了,不过代码着实垃圾。DP用循环来写还是不太熟练,用的递归。。。侥幸没T。

C. TWO ARRAYS

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define ll long long
 4 ll mod = 1000000000 + 7;
 5 ll m, n, sum = 0;
 6 ll dp[1005][1005] = {0};
 7 ll dp2[1005][1005] = {0};
 8 ll dfs(ll n, ll m){
 9     if(dp[n][m]) return dp[n][m];
10     ll sum = 0;
11     for(ll i = n; i >= 1; i--){
12        // cout << i << " " << m-1 << " " << dp[i][m-1] << endl;
13         if(dp[i][m-1] == 0){
14        // cout << i << " " << m-1 << " " << endl;
15         dp[i][m-1] = dfs(i, m-1);
16         }
17         sum += dp[i][m-1];
18     }
19     return dp[n][m] = (sum % mod);
20 }
21 ll dfs2(ll t1, ll t2){
22    if(dp2[t1][t2]) return dp2[t1][t2];
23    ll sum = 0;
24   // cout << "====\n" << endl;
25    for(ll i = t1; i <= n; i++){
26         if(dp2[i][t2-1] == 0){
27             dp2[i][t2-1] = dfs2(i, t2-1);
28         }
29         sum += dp2[i][t2-1];
30    }
31    return dp2[t1][t2] = (sum % mod);
32 }
33 int main()
34 {
35     memset(dp, 0, sizeof(dp));
36     cin >> n >> m;
37     for(int i = 1; i <= n; i++)
38         dp2[i][1] = 1;
39     dfs2(n, m);
40    // cout << "====" << endl;
41  
42  
43     for(int i = 1; i <= n; i++)
44         dp[i][1] = i;
45     dfs(n, m);
46     for(int i = 1; i <= n; i++){
47         dp[i][m] = dfs(i, m);
48         dp2[i][m] = dfs2(i, m);
49     }
50     ll sum = 0;
51     sum = 0;
52     for(int i = 1; i <= n; i++){
53         //cout << dp2[i][m]  << " " << dp[i][m]  << endl;
54         sum += (dp2[i][m] * dp[i][m]) % mod;
55         sum %= mod;
56     }
57     cout <<sum <<endl;
58 }

下面是大佬的代码

 1 #include<bits/stdc++.h>
 2 #define fi first
 3 #define se second
 4 #define LL long long
 5 #define PI std::pair<int,int>
 6 #define MP std::make_pair
 7 const int N=1005,M=11,P=1000000007;
 8 int f[M][N];
 9 int main(){
10     int n,m;
11     scanf("%d%d",&n,&m);
12     for(int i=1;i<=n;i++)f[1][i]=1;
13     for(int i=1;i<=m-1;i++){
14         for(int j=1;j<=n;j++) for(int k=j;k<=n;k++)(f[i+1][k]+=f[i][j])%=P;
15     }
16     int ans=0;
17     for(int j=1;j<=n;j++) for(int k=j;k<=n;k++)ans=(ans+(LL)f[m][j]*f[m][n-k+1])%P;
18     printf("%d",ans);
19 }

把 i与n或者1的差值看作是一段任由发挥的空间即可;

D. Minimax Problem

      D题只能说看完题解后感觉想法太奇妙了

      列数最大是8,用二进制数表示某一位是否符合条件,

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define maxn 1000000000
 4 #define ll long long
 5 int vis[300] = {0};
 6 int t[300005][10];
 7 int m, n;
 8 int t1, t2;
 9 bool check(int x){
10      memset(vis, 0, sizeof(vis));
11      int num;
12      for(int i = 1; i <= m; i++){
13         num = 0;
14         for(int j = 1; j <= n; j++){
15             if(t[i][j] >= x){
16                 num |= (1 << (j-1));//(二进制数储存i行第j列是否符合条件)
17             }
18         }
19         vis[num] = i;
20      }
21      for(int i = 0; i <= 256; i++){
22         for(int j = 0; j <= 256; j++){
23             if(vis[i] && vis[j] && (i | j) == ((1 << n) - 1)){
24                 t1 = vis[i];
25                 t2 = vis[j];
26                 return true;
27             }
28         }
29      }
30 
31      return false;
32 }
33 int main(){
34     scanf("%d%d", &m, &n);
35     for(int i = 1; i <= m; i++)
36     for(int j = 1; j <= n; j++)
37     scanf("%d", &t[i][j]);
38     int l = 0, r = maxn, mid;
39     while(l < r){
40         int mid = (l+r) / 2;
41         if(check(mid)){
42             l = mid + 1;
43         }
44         else{
45             r = mid;
46         }
47     }
48     cout << t1 << " " << t2 << endl;
49 }

猜你喜欢

转载自www.cnblogs.com/jrjxt/p/12202842.html