Submission #511463

# Submission time Handle Problem Language Result Execution time Memory
511463 2022-01-15T22:14:17 Z rodov Skyscraper (JOI16_skyscraper) C++14
100 / 100
65 ms 23884 KB
#include <bits/stdc++.h>
 
using namespace std;
 
typedef long long ll;
typedef pair<int,int> ii;
typedef vector<int> vi;
typedef vector<ii> vii;
typedef long double ld;
 
#define fi first
#define se second
#define pb push_back
#define mp make_pair
 
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 a[101];
const ll MOD = 1e9 + 7;
 
int main()
{
	ios_base::sync_with_stdio(0); cin.tie(0);
	int n, l;
	cin>>n>>l;
	for(int i = 0; i < n; i++)
	{
		cin>>a[i];
	}
	sort(a, a + n);
	if(n == 1) //special case
	{
		cout << 1;
		return 0;
	}
	a[n] = 10000; //inf for simplicity
	if(a[1] - a[0] <= l) dp[1][1][a[1] - a[0]][1] = 2; //fill a[0] at one of the endpoints, there are 2 endpoints to fill.
	if(2*(a[1] - a[0]) <= l) dp[1][1][2*(a[1] - a[0])][0] = 1; //fill a[0] in the middle, positions doesn't matter.
 
	for(int i = 1; i < n; i++)
	{
		int diff = a[i + 1] - a[i]; //this thing is "INF" if i = n - 1.
		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; //this value does not exist
					//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] = (dp[i + 1][j][k + diff*(2*j - z - 1)][z + 1] + dp[i][j][k][z]*(2-z)*j)%MOD; //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] = (dp[i + 1][j][k + diff*(2*j - z - 1)][z + 1] + dp[i][j][k][z]*(2-z)*(j-z))%MOD; //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] = (dp[i + 1][j + 1][k + diff*(2*j - z + 1)][z + 1] + dp[i][j][k][z]*(2-z))%MOD; //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] = (dp[i + 1][j + 1][k + diff*(2*j - z + 2)][z] + dp[i][j][k][z])%MOD; //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] = (dp[i + 1][j][k + diff*(2*j - z)][z] + dp[i][j][k][z]*(2*j - z))%MOD; //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] = (dp[i + 1][j - 1][k + diff*(2*j - z - 2)][z] + dp[i][j][k][z]*j*(j-1))%MOD; //there are jP2 possible merges
						}
						if(z == 1)
						{
							dp[i + 1][j - 1][k + diff*(2*j - z - 2)][z] = (dp[i + 1][j - 1][k + diff*(2*j - z - 2)][z] + dp[i][j][k][z]*(j-1)*(j-1))%MOD; //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] = (dp[i + 1][j - 1][k + diff*(2*j - z - 2)][z] + dp[i][j][k][z])%MOD; //there's only 1 place it can go.
							}
							else
							{
								dp[i + 1][j - 1][k + diff*(2*j - z - 2)][z] = (dp[i + 1][j - 1][k + diff*(2*j - z - 2)][z] + dp[i][j][k][z]*(j-2)*(j-1))%MOD; //there're (j-2)P2 + 2(j-2) possiblilities
							}
						}
					}
				}
			}
		}
	}
 
	ll answer = 0;
	for(int i = 0; i <= l; i++)
	{
		answer = (answer + dp[n][1][i][2])%MOD; //sum the dp values for all possible sums
	}
	cout << answer << '\n';
	return 0;
}
# Verdict Execution time Memory Grader output
1 Correct 0 ms 204 KB Output is correct
2 Correct 1 ms 332 KB Output is correct
3 Correct 0 ms 332 KB Output is correct
4 Correct 1 ms 332 KB Output is correct
5 Correct 1 ms 460 KB Output is correct
6 Correct 1 ms 460 KB Output is correct
7 Correct 1 ms 332 KB Output is correct
8 Correct 1 ms 460 KB Output is correct
9 Correct 1 ms 460 KB Output is correct
10 Correct 1 ms 460 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 1 ms 588 KB Output is correct
2 Correct 1 ms 460 KB Output is correct
3 Correct 1 ms 588 KB Output is correct
4 Correct 1 ms 460 KB Output is correct
5 Correct 1 ms 460 KB Output is correct
6 Correct 1 ms 584 KB Output is correct
7 Correct 1 ms 460 KB Output is correct
8 Correct 1 ms 588 KB Output is correct
9 Correct 1 ms 704 KB Output is correct
10 Correct 1 ms 448 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 0 ms 204 KB Output is correct
2 Correct 1 ms 332 KB Output is correct
3 Correct 0 ms 332 KB Output is correct
4 Correct 1 ms 332 KB Output is correct
5 Correct 1 ms 460 KB Output is correct
6 Correct 1 ms 460 KB Output is correct
7 Correct 1 ms 332 KB Output is correct
8 Correct 1 ms 460 KB Output is correct
9 Correct 1 ms 460 KB Output is correct
10 Correct 1 ms 460 KB Output is correct
11 Correct 1 ms 588 KB Output is correct
12 Correct 1 ms 460 KB Output is correct
13 Correct 1 ms 588 KB Output is correct
14 Correct 1 ms 460 KB Output is correct
15 Correct 1 ms 460 KB Output is correct
16 Correct 1 ms 584 KB Output is correct
17 Correct 1 ms 460 KB Output is correct
18 Correct 1 ms 588 KB Output is correct
19 Correct 1 ms 704 KB Output is correct
20 Correct 1 ms 448 KB Output is correct
21 Correct 1 ms 1100 KB Output is correct
22 Correct 65 ms 23884 KB Output is correct
23 Correct 61 ms 7932 KB Output is correct
24 Correct 45 ms 11980 KB Output is correct
25 Correct 48 ms 9156 KB Output is correct
26 Correct 49 ms 8548 KB Output is correct
27 Correct 23 ms 9600 KB Output is correct
28 Correct 28 ms 11968 KB Output is correct
29 Correct 50 ms 16452 KB Output is correct
30 Correct 52 ms 9452 KB Output is correct