結果
問題 |
No.54 Happy Hallowe'en
|
ユーザー |
|
提出日時 | 2014-10-30 23:14:56 |
言語 | C++11(廃止可能性あり) (gcc 13.3.0) |
結果 |
WA
|
実行時間 | - |
コード長 | 1,488 bytes |
コンパイル時間 | 928 ms |
コンパイル使用メモリ | 68,748 KB |
実行使用メモリ | 6,820 KB |
最終ジャッジ日時 | 2024-12-30 14:35:52 |
合計ジャッジ時間 | 3,564 ms |
ジャッジサーバーID (参考情報) |
judge5 / judge3 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
other | AC * 17 WA * 2 |
ソースコード
// 想定解法: DP #include <iostream> #include <vector> #include <set> #include <algorithm> using namespace std; #define REP(i, n) for(int(i)=0;(i)<(n);++(i)) #define RREP(i, n) for(int(i)=(n)-1;(i)>=0;--(i)) void rc(int v,int mn,int mx){if(v<mn||mx<v){cerr<<"error"<<endl;}} const int MAXN = 10000; const int MAXV = 10000; const int MAXT = 10000; int N,V,T; set<int> s[MAXT+1]; bool dp[MAXT+1]; int main(){ cin >> N; rc(N,1,MAXN); int maxt = 0; REP(i,N){ cin >> V >> T; rc(V,1,MAXV); rc(T,1,MAXT); s[T-1].insert(V); maxt = max(maxt, T); } dp[0] = true; int res = 0; REP(i,maxt){ RREP(j,i+1){ if(!dp[j]) continue; for(auto it = s[i].begin(); it != s[i].end(); ++it){ int v = *it; int k = j + v; if(k < maxt) dp[k] = true; res = max(res, k); } } } cout << res << endl; return 0; } /* 解説 s[i]には所持数i以下に適用できるデータを持ち、 閾値が低い家から順に処理していきます。 dp[j]には所持数jが存在するかを持たせ、 現在の所持数が i以下の場合に、+V することが出来るので i以下のjについて dp[j] が存在する場合 dp[j+V] にフラグを立てます。 重複して+Vしないよう、i→0 の順に処理する必要があります。 */