結果
| 問題 |
No.200 カードファイト!
|
| コンテスト | |
| ユーザー |
yaoshimax
|
| 提出日時 | 2015-05-01 14:23:47 |
| 言語 | C++11(廃止可能性あり) (gcc 13.3.0) |
| 結果 |
AC
|
| 実行時間 | 3 ms / 2,000 ms |
| コード長 | 3,435 bytes |
| コンパイル時間 | 800 ms |
| コンパイル使用メモリ | 94,128 KB |
| 実行使用メモリ | 5,248 KB |
| 最終ジャッジ日時 | 2024-10-15 08:59:30 |
| 合計ジャッジ時間 | 1,707 ms |
|
ジャッジサーバーID (参考情報) |
judge3 / judge2 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 |
| other | AC * 26 |
ソースコード
#include <cstdio>
#include <queue>
#include <cstdlib>
#include <cmath>
#include <climits>
#include <cfloat>
#include <map>
#include <utility>
#include <set>
#include <iostream>
#include <memory>
#include <string>
#include <vector>
#include <algorithm>
#include <functional>
#include <sstream>
#include <complex>
#include <stack>
#include <queue>
#include <cstring>
using namespace std;
//これは何?
//最小費用流を計算するためのライブラリ。
//枝を定義する構造体edge
//枝を追加するaddedge
//最小費用流を計算するmincost関数からなる。
//なお、グラフはvector<edge> graph[]として表現される。
struct edge{ int to; int cap; int cost; int rev;};
int mincost( vector<edge> graph[], int size, int start, int end, int F ){
bool changed = true;
int prev[size];
int prevind[size];
int dist[size];
int cost = 0;
while( F > 0 ){
memset( prev, -1, sizeof(prev));
memset( prevind, -1, sizeof(prev));
for( int i = 0 ; i < size; i++ ) dist[i] = INT_MAX/2;
dist[start]=0;
changed = true;
while( changed ){
changed = false;
for( int i = 0 ; i < size; i++ ){
for( int j = 0 ; j < (int)graph[i].size(); j++ ){
//cout << i <<"-"<< graph[i][j].to <<",";
edge e = graph[i][j];
if( e.cap > 0 && dist[i]+e.cost < dist[e.to] ){
changed = true;
dist[e.to] = dist[i]+e.cost;
prev[e.to] = i;
prevind[e.to] = j;
}
}
}
}
//for( int i = 0 ; i < size; i++ ) cout << dist[i]<< " , " ;
//cout << endl;
if( dist[end] == INT_MAX/2){
return -1;
}
// calc flaw
int f = INT_MAX;
int p = end;
while( p != start ){
f = min(f, graph[prev[p]][prevind[p]].cap );
p = prev[p];
}
//cout << endl;
f =min( F, f );
// exec flaw
p = end;
while( p != start){
graph[prev[p]][prevind[p]].cap -= f;
int ind = graph[prev[p]][prevind[p]].rev;
graph[p][ind].cap += f;
cost += f*graph[prev[p]][prevind[p]].cost;
p = prev[p];
}
F-=f;
}
return cost;
}
void addedge( vector<edge> graph[],int from, int to, int cap, int cost ){
//枝を追加する。逆向きには容量0でコストが真逆な枝を追加しておく。
graph[from].push_back( (edge){to,cap,cost,(int)graph[to].size()} );
graph[to].push_back( (edge){from,0,-cost, (int)graph[from].size()-1} );
return;
}
int main(){
int N,A,C;
vector<edge> graph[250];
cin >> N;
cin >> A;
int B[A];
for( int i = 0 ; i <A ;i++){
cin >> B[i];
}
cin >> C;
int D[C];
for( int i = 0 ; i < C; i++ ){
cin >> D[i];
}
sort(B,B+A);
reverse(B,B+A);
sort(D,D+C);
for( int i = 0 ; i < N; i++ ){
addedge(graph,0,i+1,1,0);
addedge(graph,N+i+1,249,1,0);
}
for( int i = 0 ; i <N; i++ ){
int start = (i/A)*A;
int end = min(start+A-1,N-1);
for( int j = 0 ; j < N; j++ ){
int start2 = (j/C)*C;
int end2 = min(start2+C-1,N-1);
if( end<start2 || end2<start) continue;
if(B[i%A] <= D[j%C]){
//cout << i<<"--1->"<<N+j<<endl;
addedge(graph,i+1,N+1+j,1,1);
}
else{
//cout << i<<"--0->"<<N+j<<endl;
addedge(graph,i+1,N+1+j,1,0);
}
}
}
cout << N-mincost(graph,250,0,249,N)<<endl;
return 0;
}
yaoshimax