Submission #205989

#TimeUsernameProblemLanguageResultExecution timeMemory
205989stefdascaSkyscraper (JOI16_skyscraper)C++14
100 / 100
109 ms23928 KiB
#include<bits/stdc++.h> #define god dimasi5eks #pragma GCC optimize("O3") #define fi first #define se second #define pb push_back #define pf push_front #define mod 1000000007 #define dancila 3.14159265359 #define eps 1e-9 // #define fisier 1 using namespace std; typedef long long ll; int add(int a, int b) { int x = a+b; if(x >= mod) x -= mod; if(x < 0) x += mod; return x; } ll mul(ll a, ll b) { return (a*b) % mod; } ll pw(ll a, ll b) { ll ans = 1; while(b) { if(b & 1) ans = (ans * a) % mod; a = (a * a) % mod; b >>= 1; } return ans; } mt19937 rng(chrono::steady_clock::now().time_since_epoch().count()); long long rand_seed() { long long a = rng(); return a; } ll dp[101][101][1001][3]; /* dp[i][j][k][l] : i - number of numbers placed j - number of connected components k - total sum currently (filling empty spaces with a_{i} (0-indexed) l - number of endpoints that are filled */ ll v[101]; int main() { ios_base::sync_with_stdio(false); cin.tie(NULL); int n, l; cin >> n >> l; for(int i = 0; i < n; i++) cin >> v[i]; sort(v, v + n); if(n == 1) { cout << 1; return 0; } v[n] = (1<<20); if(v[1] - v[0] <= l) dp[1][1][v[1] - v[0]][1] = 2; //fill a[0] at one of the endpoints, there are 2 endpoints to fill. if(2 * (v[1] - v[0]) <= l) dp[1][1][2 * (v[1] - v[0])][0] = 1; //fill a[0] in the middle, positions doesn't matter. for(int i = 1; i < n; i++) for(int j = 1; j <= i; j++) for(int k = 0; k <= l; k++) for(int z = 0; z < 3; z++) { if(!dp[i][j][k][z]) continue; int diff = v[i + 1] - v[i]; //First, we try to fill one of the ends if(z < 2 && k + diff * (2 * j - z - 1) <= l) //there are 2*j - z - 1 positions that we're supposed to "upgrade" (-1 because one of the positions is merged with the endpoints after this move) { if(i == n - 1) dp[i + 1][j][k + diff * (2 * j - z - 1)][z + 1] = add(dp[i + 1][j][k + diff * (2 * j - z - 1)][z + 1], mul(dp[i][j][k][z], (2-z) * j)); //we have j con. comp. to choose to merge with else if(z == 0 || j > 1) //otherwise this coincides with i == n - 1 dp[i + 1][j][k + diff * (2 * j - z - 1)][z + 1] = add(dp[i + 1][j][k + diff * (2 * j - z - 1)][z + 1], mul(dp[i][j][k][z], (2-z)*(j-z))); //can only merge with the con comp. that are not connected to ends. if(k + diff * (2 * j - z + 1) <= l) //now we create a new cc. dp[i + 1][j + 1][k + diff * (2 * j - z + 1)][z + 1] = add(dp[i + 1][j + 1][k + diff * (2 * j - z + 1)][z + 1], mul(dp[i][j][k][z], (2-z))); //we can choose one of the ends to create } //Next, we dont fill the ends. //Part 1 : Create new cc if(k + diff*(2*j - z + 2) <= l) //2 new positions to "upgrade" { dp[i + 1][j + 1][k + diff*(2*j - z + 2)][z] = add(dp[i + 1][j + 1][k + diff*(2*j - z + 2)][z], dp[i][j][k][z]); //nothing new happens } //Part 2 : Stick to one cc if(k + diff*(2*j - z) <= l) //no new positions to "upgrade" { dp[i + 1][j][k + diff*(2*j - z)][z] = add(dp[i + 1][j][k + diff*(2*j - z)][z], mul(dp[i][j][k][z], (2*j - z))); //we can merge in 2*j - z possible positions } //Part 3 : Merge two ccs together if((k + diff*(2*j - z - 2) <= l) && (j >= 2) && (i == n - 1 || j > 2 || z < 2)) { if(z == 0) { dp[i + 1][j - 1][k + diff*(2*j - z - 2)][z] = add(dp[i + 1][j - 1][k + diff*(2*j - z - 2)][z], mul(dp[i][j][k][z], j*(j-1))); //there are jP2 possible merges } if(z == 1) { dp[i + 1][j - 1][k + diff*(2*j - z - 2)][z] = add(dp[i + 1][j - 1][k + diff*(2*j - z - 2)][z], mul(dp[i][j][k][z], (j-1)*(j-1))); //there are (j-1)P2+(j-1) merges } if(z == 2) { if(i == n - 1) { dp[i + 1][j - 1][k + diff*(2*j - z - 2)][z] = add(dp[i + 1][j - 1][k + diff*(2*j - z - 2)][z], dp[i][j][k][z]); //there's only 1 place it can go. } else { dp[i + 1][j - 1][k + diff*(2*j - z - 2)][z] = add(dp[i + 1][j - 1][k + diff*(2*j - z - 2)][z], mul(dp[i][j][k][z], (j-2)*(j-1))); //there're (j-2)P2 + 2(j-2) possiblilities } } } } ll answer = 0; for(int i = 0; i <= l; i++) answer = add(answer, dp[n][1][i][2]); cout << answer << '\n'; return 0; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...