Submission #1239556

#TimeUsernameProblemLanguageResultExecution timeMemory
1239556MuhammadSaramCarnival Tickets (IOI20_tickets)C++20
39 / 100
3109 ms2162688 KiB
#include "tickets.h"
#include <bits/stdc++.h>

using namespace std;

#define ll long long
#define all(v) v.begin(), v.end()

const ll inf = -1e18;

vector<vector<int>> construct(vector<vector<int>> a,int k)
{
	int n=a.size(), m=a[0].size();
	ll dp1[n+1][2*n*k+1];
	ll* dp[n+1];
	for (int i=0;i<=n;i++)
	{
		dp[i]=dp1[i]+n*k;
		for (int j=-n*k;j<=n*k;j++)
			dp[i][j]=inf;
	}
	ll pre[n][m+1]={};
	for (int i=0;i<n;i++)
		for (int j=0;j<m;j++)
			pre[i][j+1]=pre[i][j]+a[i][j];
	dp[0][0]=0;
	for (int i=0;i<n;i++)
		for (int j=0;j<=k;j++)
		{
			int ad=k-2*j;
			for (int l=-k*(i+1)-min(0,ad);l+ad<=(i+1)*k;l++)
				dp[i+1][l+ad]=max(dp[i+1][l+ad],dp[i][l]-pre[i][j]+pre[i][m]-pre[i][m-(k-j)]);
		}
	int id=0,s=n-1;
	ll val=dp[n][id];
	vector<vector<int>> ans(n);
	while (s>=0)
	{
		for (int j=0;j<=k;j++)
		{
			int ad=k-2*j;
			if (id-ad>=-n*k && id-ad<=n*k)
				if (dp[s][id-ad]-pre[s][j]+pre[s][m]-pre[s][m-(k-j)]==val)
				{
					vector<int> v;
					for (int l=0;l<j;l++) v.push_back(a[s][l]);
					for (int l=m-(k-j);l<m;l++) v.push_back(a[s][l]);
					ans[s]=v;
					val=dp[s][id-ad], id-=ad;
					break;
				}
		}
		s--;
	}
	return ans;
}

long long find_maximum(int k, vector<vector<int>> a)
{
	int n=a.size(), m=a[0].size();
	a=construct(a,k);
	vector<int> val;
	multiset<int> se1,se2;
	ll ans=0;
	for (int i=0;i<n;i++)
		for (int j:a[i]) val.push_back(j),ans+=j;
	sort(all(val));
	for (int i=0;i<n*k;i++)
		if (i<n*k/2) se1.insert(val[i]),ans-=val[i]*2;
		else se2.insert(val[i]);
	int id[n][2], cnt[n]={};
	for (int i=0;i<n;i++)
	{
		id[i][0]=0, id[i][1]=m-1;
		for (int j=k-1;j>=0;j--)
		{
			auto it=se1.find(a[i][j]);
			if (it!=se1.end())
				se1.erase(it);
			else
				cnt[i]++, se2.erase(se2.find(a[i][j]));
		}
	}
	priority_queue<pair<int,int>,vector<pair<int,int>>,greater<pair<int,int>>> se;
	vector<vector<int>> v(n, vector<int>(m,-1));
	for (int r=0;r<k;r++)
	{
		for (int i=0;i<n;i++)
			se.push({cnt[i],i});
		for (int i=0;i<n;i++)
		{
			pair<int,int> p=se.top();se.pop();
			if (i<n/2)
				v[p.second][id[p.second][0]++]=r;
			else
				v[p.second][id[p.second][1]--]=r, cnt[p.second]--;
		}
	}
	allocate_tickets(v);
	return ans;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...