/* FILE: pirates.cpp last change: 5-Oct-2013 author: Romeo Rizzi * a solver for problem pirates based on dynamic programming */ //#define NDEBUG // NDEBUG definita nella versione che consegno #include #ifndef NDEBUG # include // uso di cin e cout non consentito in versione finale #endif #include #include using namespace std; const int MAX_N = 1000; int n; int T; int rule; int Q; struct pair_t { int pirate; int coins; }; bool cmp_coins(const pair_t& a, const pair_t& b) { return (a.coins < b.coins); } bool cmp_pirate(const pair_t& a, const pair_t& b) { return (a.pirate < b.pirate); } pair_t realization[MAX_N+1]; pair_t proposal[MAX_N+1]; int main() { ifstream fin("input.txt"); assert( fin ); fin >> n >> T >> rule; assert( n <= MAX_N ); if( rule == 4 ) fin >> Q; fin.close(); // caso base (c'e' un solo pirata, che si prende tutto): realization[0].pirate = 1; realization[0].coins = T; for(int i = 1; i < n; i++) { realization[i].pirate = i+1; realization[i].coins = -1;} for(int n_alive = 2; n_alive <= n; n_alive++ ) { for(int i = 0; i < n_alive-1; i++) { proposal[i].coins = realization[i].coins +1; // quanto mi costerebbe farlo votare a favore proposal[i].pirate = realization[i].pirate; // nome } stable_sort(proposal, proposal+n_alive-1, cmp_coins); // greed -> sort, anarchic -> stable sort int tot_cost = 0; int soglia; switch( rule ) { case (0): soglia = (n_alive+1)/2; break; case (1): soglia = (n_alive+1)/2; break; case (2): soglia = n_alive/2; break; case (3): soglia = n_alive/3; break; case (4): soglia = Q; break; } int j = 0; for(int n_votes = 1; (n_votes < soglia) && (tot_cost <= T); n_votes++, j++) { tot_cost += proposal[j].coins; } if( tot_cost <= T ) { proposal[n_alive-1].pirate = n_alive; proposal[n_alive-1].coins = T - tot_cost; while( j < n_alive-1 ) proposal[j++].coins = 0; sort(proposal, proposal+n_alive-1, cmp_pirate); for(int i = 0; i < n_alive; i++) { realization[i].coins = proposal[i].coins; realization[i].pirate = proposal[i].pirate; } } // cout << " n = " << n_alive << ", T = " << T << endl; // for(int i = 0; i < n_alive; i++) // cout << realization[i].pirate % 10 << " "; // cout << endl; // for(int i = 0; i < n_alive; i++) // cout << realization[i].coins << " "; // cout << endl << endl; } ofstream fout("output.txt"); for(int i = 0; i < n; i++) fout << realization[i].coins << " " << endl; fout.close(); return 0; }