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