Problem:
Problem A:
Cubist Artwork
International Center for Picassonian Cubism
is a Spanish national museum of cubist artworks,
dedicated to Pablo Picasso. The center held a competition for an artwork that will be displayed
in front of the facade of the museum building. The artwork is a collection of cubes that are
piled up on the ground and is intended to amuse visitors, who will be curious how the shape of
the collection of cubes changes when it is seen from the front and the sides.
The artwork is a collection of cubes with edges of one foot long and is built on a flat ground
that is divided into a grid of one foot by one foot squares. Due to some technical reasons, cubes
of the artwork must be either put on the ground, fitting into a unit square in the grid, or put
on another cube in the way that the bottom face of the upper cube exactly meets the top face
of the lower cube. No other way of putting cubes is possible.
You are a member of the judging committee responsible for selecting one out of a plenty of
artwork proposals submitted to the competition. The decision is made primarily based on
artistic quality but the cost for installing the artwork is another important factor. Your task is
to investigate the installation cost for each proposal. The cost is proportional to the number of
cubes, so you have to figure out the minimum number of cubes needed for installation.
Each design proposal of an artwork consists of the front view and the side view (the view seen
from the right-hand side), as shown in Figure 1.
Figure 1: An example of an artwork proposal
The front view (resp., the side view) indicates the maximum heights of piles of cubes for each
column line (resp., row line) of the grid.
There are several ways to install this proposal of artwork, such as the following figures.
In these figures, the dotted lines on the ground indicate the grid lines. The left figure makes use
of 16 cubes, which is not optimal. That is, the artwork can be installed with a fewer number
of cubes. Actually, the right one is optimal and only uses 13 cubes. Note that, a single pile of
height three in the right figure plays the roles of two such piles in the left one.
Notice that swapping columns of cubes does not change the side view. Similarly, swapping
rows does not change the front view. Thus, such swaps do not change the costs of building the
artworks.
For example, consider the artwork proposal given in Figure 2.
Figure 2: Another example of artwork proposal
An optimal installation of this proposal of artwork can be achieved with 13 cubes, as shown
in the following figure, which can be obtained by exchanging the rightmost two columns of the
optimal installation of the artwork of Figure 1.
Input
The input is a sequence of datasets. The end of the input is indicated by a line containing two
zeros separated by a space. Each dataset is formatted as follows.
w d
h
1
h
2
...
h
w
h'
1
h'
2
...
h'
d
The integers
w
and
d
separated by a space are the numbers of columns and rows o
...(truncated)

Submitted solutions:

code_snippet: #pragma region Macros
#include <bits/stdc++.h>
using namespace std;
template <class T> inline bool chmax(T &a, T b) {
    if(a < b) {
        a = b;
        return 1;
    }
    return 0;
}
template <class T> inline bool chmin(T &a, T b) {
    if(a > b) {
        a = b;
        return 1;
    }
    return 0;
}
#ifdef DEBUG
template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
    os << '(' << p.first << ',' << p.second << ')';
    return os;
}
template <class T> ostream &operator<<(ostream &os, const vector<T> &v) {
    os << '{';
    for(int i = 0; i < (int)v.size(); i++) {
        if(i) { os << ','; }
        os << v[i];
    }
    os << '}';
    return os;
}
void debugg() { cerr << endl; }
template <class T, class... Args>
void debugg(const T &x, const Args &... args) {
    cerr << " " << x;
    debugg(args...);
}
#define debug(...)                                                             \
    cerr << __LINE__ << " [" << #__VA_ARGS__ << "]: ", debugg(__VA_ARGS__)
#define dump(x) cerr << __LINE__ << " " << #x << " = " << (x) << endl
#else
#define debug(...) (void(0))
#define dump(x) (void(0))
#endif

struct Setup {
    Setup() {
        cin.tie(0);
        ios::sync_with_stdio(false);
        cout << fixed << setprecision(15);
    }
} __Setup;

using ll = long long;
#define ALL(v) (v).begin(), (v).end()
#define RALL(v) (v).rbegin(), (v).rend()
#define FOR(i, a, b) for(int i = (a); i < int(b); i++)
#define REP(i, n) FOR(i, 0, n)
const int INF = 1 << 30;
const ll LLINF = 1LL << 60;
constexpr int MOD = 1000000007;
const int dx[4] = {1, 0, -1, 0};
const int dy[4] = {0, 1, 0, -1};

void Case(int i) { cout << "Case #" << i << ": "; }
int popcount(int x) { return __builtin_popcount(x); }
ll popcount(ll x) { return __builtin_popcountll(x); }
#pragma endregion Macros

int main() {
    while(1) {
        int N, M;
        cin >> N >> M;
        if(N == 0) break;
        vector<int> a(N), b(M);
        REP(i, N) cin >> a[i];
        REP(i, M) cin >> b[i];

        if(N < M) {
            swap(N, M);
            swap(a, b);
        } // N >= M
        int ans = INF;
        vector<int> ord(N);
        iota(ALL(ord), 0);

        do {
            int cost = 0;
            REP(i, M) {
                if(a[ord[i]] == b[i]) cost += b[i];
                else cost += a[ord[i]] + b[i];
            }
            FOR(i, M, N) cost += a[ord[i]];
            chmin(ans, cost);
        }while(next_permutation(ALL(ord)));

        cout << ans << "\n";
    }
}
accuracy: 1
time_ms: 840
memory_kb: 3460
final_rank: 2

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define modulo 1000000007
#define mod(mod_x) ((((long long)mod_x+modulo))%modulo)
#define Inf 2000000005


int main(){
	
	
	
	while(true){
		int w,d;
		cin>>w>>d;
		if(w==0)break;
		
		vector<vector<int>> dp(w+1,vector<int>(1<<d,Inf));
		dp[0][0] = 0;
		
		vector<int> hw(w),hd(d);
		for(int i=0;i<w;i++)cin>>hw[i];
		for(int i=0;i<d;i++)cin>>hd[i];
		
		for(int i=0;i<w;i++){
			for(int j=0;j<(1<<d);j++){
				if(dp[i][j]==Inf)continue;
				
				for(int k=0;k<(1<<d);k++){
					int sum = 0;
					bool f = false;
					int mask = 0;
					for(int l=0;l<d;l++){
						if((k>>l)&1){
							if(hw[i]>hd[l]){
								sum += hd[l];
								mask |= (1<<l);
							}
							else{
								f = true;
								sum += hw[i];
								if(hw[i]==hd[l])mask |= (1<<l);
							}
						}
					}
					if(!f)continue;
					dp[i+1][j|mask] = min(dp[i+1][j|mask],dp[i][j]+sum);
				}
				
			}
		}
		
		cout<<dp.back().back()<<endl;
		
	}
	
	
	return 0;
}
accuracy: 1
time_ms: 3390
memory_kb: 3184
final_rank: 5

code_snippet: #include<iomanip>
#include<limits>
#include<thread>
#include<utility>
#include<iostream>
#include<string>
#include<algorithm>
#include<set>
#include<map>
#include<vector>
#include<stack>
#include<queue>
#include<cmath>
#include<numeric>
#include<cassert>
#include<random>
#include<chrono>
#include<unordered_set>
#include<unordered_map>
#include<fstream>
#include<list>
#include<functional>
#include<bitset>
#include<complex>
#include<tuple>
using namespace std;
typedef unsigned long long int ull;
typedef long long int ll;
typedef pair<ll,ll> pll;
typedef pair<int,int> pi;
typedef pair<double,double> pd;
typedef pair<double,ll> pdl;
#define F first
#define S second
const ll E=1e18+7;
const ll MOD=1000000007;




int main(){
    ll w,d;
    while(cin>>w>>d){
        if(w==0){break;}
    vector<ll> a(w);
    for(auto &I:a){cin>>I;}
    vector<ll> b(d);
    for(auto &I:b){cin>>I;}
    vector<vector<ll>> dp(w+1,vector<ll>(1LL<<d,MOD));
    dp[0][0]=0;
    for(int i=0;i<w;i++){
        for(int k=0;k<d;k++){
            if(a[i]>b[k]){continue;}
            for(int h=0;h<(1LL<<d);h++){
                dp[i+1][h]=min(dp[i+1][h],dp[i][h]+a[i]);
                if(a[i]==b[k]){dp[i+1][h|(1<<k)]=min(dp[i+1][h|(1<<k)],dp[i][h]+a[i]);}
                int O=((1<<d)-1)^h;
                for(int key=O;key>0;key=(key-1)&O){
                    if(key>>k&1){continue;}
                    ll sum=0;
                    for(int p=0;p<d;p++){
                        if(key>>p&1){
                            if(b[p]>a[i]){sum+=MOD;}
                            sum+=b[p];
                        }
                    }
                    if(a[i]==b[k]){
                        dp[i+1][h|(1<<k)|key]=min(dp[i+1][h|(1<<k)|key],dp[i][h]+sum+a[i]);
                    }
                    else{
                        dp[i+1][h|key]=min(dp[i+1][h|key],dp[i][h]+sum+a[i]);
                    }
                }
            }
        }
    }
    cout<<dp[w][(1LL<<d)-1]<<endl;
    }
    
    
    

    return 0;
}
accuracy: 1
time_ms: 1420
memory_kb: 3244
final_rank: 4

code_snippet: #include<stdio.h>
#include <iostream>
#include <math.h>
#include <numeric>
#include <vector>
#include <map>
#include <functional>
#include <stdio.h>
#include <array>
#include <algorithm>
#include <string>
#include <string.h>
#include <assert.h>
#include <stdio.h>
#include <queue>
#include<iomanip>
#include<bitset>
#include<stack>
#include<set>
#include<limits>
#include <complex>
using namespace std;
template < class BidirectionalIterator >
bool next_combination(BidirectionalIterator first1,
	BidirectionalIterator last1,
	BidirectionalIterator first2,
	BidirectionalIterator last2)
{
	if ((first1 == last1) || (first2 == last2)) {
		return false;
	}
	BidirectionalIterator m1 = last1;
	BidirectionalIterator m2 = last2; --m2;
	while (--m1 != first1 && !(*m1 < *m2)) {
	}
	bool result = (m1 == first1) && !(*first1 < *m2);
	if (!result) {
		// ?
		while (first2 != m2 && !(*m1 < *first2)) {
			++first2;
		}
		first1 = m1;
		std::iter_swap(first1, first2);
		++first1;
		++first2;
	}
	if ((first1 != last1) && (first2 != last2)) {
		// ?
		m1 = last1; m2 = first2;
		while ((m1 != first1) && (m2 != last2)) {
			std::iter_swap(--m1, m2);
			++m2;
		}
		// ?
		std::reverse(first1, m1);
		std::reverse(first1, last1);
		std::reverse(m2, last2);
		std::reverse(first2, last2);
	}
	return !result;
}

template < class BidirectionalIterator >
bool next_combination(BidirectionalIterator first,
	BidirectionalIterator middle,
	BidirectionalIterator last)
{
	return next_combination(first, middle, middle, last);
}



int main() {
	while (1) {
		int w, d; cin >> w >> d;
		if (!w)break;
		vector<int>ws;
		vector<int>ds;
		if (w >= d) {
			for (int i = 0; i < w; ++i) {
				int a; cin >> a; ws.push_back(a);
			}
			for (int i = 0; i <d; ++i) {
				int a; cin >> a; ds.push_back(a);
			}
		}
		else {
			for (int i = 0; i < w; ++i) {
				int a; cin >> a; ds.push_back(a);
			}
			for (int i = 0; i <d; ++i) {
				int a; cin >> a; ws.push_back(a);
			}
		}
		assert(ws.size() >= ds.size());

		vector<int>perm;
		for (int i = 0; i < ws.size(); ++i) {
			perm.push_back(i);
		}
		int finans = 500;


		do {
			int nans = 0;
			vector<bool>used(ws.size(), false);
			for (int i = 0; i < ds.size(); ++i) {
				if (ds[i] == ws[perm[i]]) {
					nans += ds[i];
				}
				else {
					nans += ds[i] + ws[perm[i]];
				}
				used[perm[i]] = true;
			}
			for (int i = 0; i < ws.size(); ++i) {
				if (!used[i]) {
					nans += ws[i];
				}
			}
			finans = min(finans, nans);

		} while (next_permutation(perm.begin(), perm.end()));
		cout << finans << endl;

	}

	return 0;
}
accuracy: 1
time_ms: 5280
memory_kb: 3116
final_rank: 6

code_snippet: #include<stdio.h>
#include <iostream>
#include <math.h>
#include <numeric>
#include <vector>
#include <map>
#include <functional>
#include <stdio.h>
#include <array>
#include <algorithm>
#include <string>
#include <string.h>
#include <assert.h>
#include <stdio.h>
#include <queue>
#include<iomanip>
#include<bitset>
#include<stack>
#include<set>
#include<limits>
#include <complex>
using namespace std;
template < class BidirectionalIterator >
bool next_combination(BidirectionalIterator first1,
	BidirectionalIterator last1,
	BidirectionalIterator first2,
	BidirectionalIterator last2)
{
	if ((first1 == last1) || (first2 == last2)) {
		return false;
	}
	BidirectionalIterator m1 = last1;
	BidirectionalIterator m2 = last2; --m2;
	while (--m1 != first1 && !(*m1 < *m2)) {
	}
	bool result = (m1 == first1) && !(*first1 < *m2);
	if (!result) {
		// ?
		while (first2 != m2 && !(*m1 < *first2)) {
			++first2;
		}
		first1 = m1;
		std::iter_swap(first1, first2);
		++first1;
		++first2;
	}
	if ((first1 != last1) && (first2 != last2)) {
		// ?
		m1 = last1; m2 = first2;
		while ((m1 != first1) && (m2 != last2)) {
			std::iter_swap(--m1, m2);
			++m2;
		}
		// ?
		std::reverse(first1, m1);
		std::reverse(first1, last1);
		std::reverse(m2, last2);
		std::reverse(first2, last2);
	}
	return !result;
}

template < class BidirectionalIterator >
bool next_combination(BidirectionalIterator first,
	BidirectionalIterator middle,
	BidirectionalIterator last)
{
	return next_combination(first, middle, middle, last);
}



int main() {
	while (1) {
		int w, d; cin >> w >> d;
		if (!w)break;
		vector<int>ws;
		vector<int>ds;
		if (w >= d) {
			for (int i = 0; i < w; ++i) {
				int a; cin >> a; ws.push_back(a);
			}
			for (int i = 0; i <d; ++i) {
				int a; cin >> a; ds.push_back(a);
			}
		}
		else {
			for (int i = 0; i < w; ++i) {
				int a; cin >> a; ds.push_back(a);
			}
			for (int i = 0; i <d; ++i) {
				int a; cin >> a; ws.push_back(a);
			}
		}
		assert(ws.size() >= ds.size());
		
		
		vector<int>perm;
		for (int i = 0; i < ws.size(); ++i) {
			perm.push_back(i);
		}
		int finans = 500;


		do {
			int nans = 0;
			for (int i = 0; i < ds.size(); ++i) {
				if (ds[i] == ws[perm[i]]) {
					nans += ds[i];
				}
				else {
					nans += ds[i] + ws[perm[i]];
				}
			}
			for (int i = ds.size(); i < ws.size(); ++i) {
				nans += ws[perm[i]];
			}
			finans = min(finans, nans);

		} while (next_permutation(perm.begin(), perm.end()));
		cout << finans << endl;

	}

	return 0;
}
accuracy: 1
time_ms: 1070
memory_kb: 3140
final_rank: 1

code_snippet: #include<iostream>

using namespace std;

#define rep(i, n) for (int i = 0; i < int(n); ++i)

int dp[11][1 << 10];

int main() {
  while (true) {
    int w, d, a[10], b[10];
    cin >> w >> d;
    if (w == 0 && d == 0) break;
    rep (i, w) cin >> a[i];
    rep (i, d) cin >> b[i];
    rep (i, 11) rep (j, 1 << 10) dp[i][j] = 1e9;
    dp[0][0] = 0;
    rep (i, d) {
      int mask1 = 0, mask2 = 0;
      rep (j, w) if (a[j] >= b[i]) mask1 |= 1 << j;
      rep (j, w) if (a[j] <= b[i]) mask2 |= 1 << j;
      rep (k, 1 << w) rep (l, 1 << w) if (mask1 & l) {
	int sum = 0;
	rep (j, w) {
	  if (l & 1 << j) {
	    sum += min(a[j], b[i]);
	  }
	}
	dp[i + 1][k | (l & mask2)] = min(dp[i + 1][k | (l & mask2)], dp[i][k] + sum);
      }
    }
    cout << dp[d][(1 << w) - 1] << endl;
  }
  return 0;
}
accuracy: 1
time_ms: 6100
memory_kb: 1204
final_rank: 2