Codeforces #367 Div.2 C. Hard problem
problem
問題要約
コスト
と
文字列
が与えられる。
をするために, コスト がかかる
うまいことをして, 文字列を辞書順に昇順()となるようにしたい.
昇順にできるとき, 最小の総コストを求めて, どう頑張ってもできない時は-1を出力する
解き方
dpを使う
: 番目の文字列までを昇順にするときに必要な最低のコスト
ここで, の時, n番目をひっくり返すときを意味し, の時, n番目をひっくり返さないことを意味する.
更新式は数式で表記すると面倒なので, ソースコード参照
事前処理として, を反転させた配列を用意しておく
注意事項
がやたらでかいので, オーバーフロー, infの定義に注意する
最終的な出力の最大値は,
SourceCode
#include <iostream> #include <queue> #include <map> #include <list> #include <vector> #include <string> #include <limits> #include <cassert> #include <fstream> #include <cstring> #include <bitset> #include <iomanip> #include <algorithm> #include <functional> #include <cstdio> #include <ciso646> using namespace std; #define FOR(i,a,b) for (int i=(a);i<(b);i++) #define RFOR(i,a,b) for (int i=(b)-1;i>=(a);i--) #define REP(i,n) for (int i=0;i<(n);i++) #define RREP(i,n) for (int i=(n)-1;i>=0;i--) #define inf 0x3f3f3f3f #define linf 0x3f3f3f3f3f3f3f3f #define PB push_back #define MP make_pair #define ALL(a) (a).begin(),(a).end() #define SET(a,c) memset(a,c,sizeof a) #define CLR(a) memset(a,0,sizeof a) #define pii pair<int,int> #define pcc pair<char,char> #define pic pair<int,char> #define pci pair<char,int> #define VS vector<string> #define VI vector<int> #define DEBUG(x) cout<<#x<<": "<<x<<endl #define MIN(a,b) (a>b?b:a) #define MAX(a,b) (a>b?a:b) #define pi 2*acos(0.0) #define INFILE() freopen("in0.txt","r",stdin) #define OUTFILE()freopen("out0.txt","w",stdout) #define in scanf #define out printf #define ll long long #define ull unsigned long long #define eps 1e-14 #define FST first #define SEC second // n次元配列の初期化。第2引数の型のサイズごとに初期化していく。 template<typename A, size_t N, typename T> void Fill(A (&array)[N], const T &val){ std::fill( (T*)array, (T*)(array+N), val ); } int main(void) { int N; cin >> N; vector<int> C(N); for(auto &a:C) cin >> a; vector<string> S(N); for(auto &a:S) cin >> a; vector<string> revS = S; REP(i,N) reverse(ALL(revS[i])); ll dp[100001][2] = {}; REP(i,100001) REP(j,2) dp[i][j] = (ll)(1e14); dp[0][0] = 0; dp[0][1] = C[0]; FOR(index, 0,N-1){ if(S[index] <= S[index+1]) dp[index+1][0] = min(dp[index+1][0], dp[index][0]); if(revS[index] <= S[index+1]) dp[index+1][0] = min(dp[index+1][0], dp[index][1]); if(S[index] <= revS[index+1]) dp[index+1][1] = min(dp[index+1][1], dp[index][0]+C[index+1]); if(revS[index] <= revS[index+1]) dp[index+1][1] = min(dp[index+1][1], dp[index][1]+C[index+1]); } ll res = min(dp[N-1][0], dp[N-1][1]); cout << (res>=1e14?-1:res) << endl; return 0; }
Codeforces #366 Div.2 C. Thor
Question
問題要約
個のクエリが渡される クエリは以下の書式で渡される
t x
ここで,
- の時: アプリケーションが通知を生成する
- の時: アプリケーションが生成した通知をすべて読む (過去に読んだやつももう一度読む)
- の時: 生成された通知を, アプリケーション関係なく, 最初から数えて回目までのものをすべて読む.
各クエリ毎に, まだ読んでいない通知を出力する.
やること
以下の4つを用意する(少し冗長な気がする)
(は, アプリケーションの個数)
- app[アプリの番号]: 何個未読の通知を持っているか
- queue addedTime[アプリの番号]: いつ通知されたか
- memo[生成された順番]: なにが生成されたか
- sum: 現在の個数
この4つを実装し, 問題文のとおりに書くだけ 時間がギリギリなので.at()とかでアクセスしたらTLEした.
SourceCode
#include <iostream> #include <queue> #include <map> #include <list> #include <vector> #include <string> #include <limits> #include <cassert> #include <fstream> #include <cstring> #include <bitset> #include <iomanip> #include <algorithm> #include <functional> #include <cstdio> #include <ciso646> #include <array> #include <cmath> using namespace std; #define FOR(i,a,b) for (int i=(a);i<(b);i++) #define RFOR(i,a,b) for (int i=(b)-1;i>=(a);i--) #define REP(i,n) for (int i=0;i<(n);i++) #define RREP(i,n) for (int i=(n)-1;i>=0;i--) #define inf 0x3f3f3f3f #define uinf 0x3f3f3f3f3f3f3f3f #define CLEAR(a) a = decltype(a)() #define MP make_pair #define ALL(a) (a).begin(),(a).end() #define pii pair<int ,int> #define pcc pair<char,char> #define pic pair<int,char> #define pci pair<char,int> #define VS vector<string> #define VI vector<int> #define VVI vector<vector<int>> #define DEBUG(x) cout<<#x<<": "<<x<<endl #define pi 2*acos(0.0) #define INFILE() freopen("in.txt","r",stdin) #define OUTFILE() freopen("out.txt","w",stdout) #define ll long long #define ull unsigned long long #define eps 1e-14 #define FIN std::ifstream cin("D:\input.txt") const int MOD = 1e9 + 7; signed int main(void) { ios::sync_with_stdio(false); int N, Q; cin >> N >> Q; vector<int> app(N + 1); vector<queue<int>> addedTime(N + 1); vector<int> memo; memo.reserve(Q+1); int readtime = 0; int sum = 0; REP(i, Q) { int t, x; cin >> t >> x; if (t == 1) { memo.push_back(x); app[x]++; addedTime[x].push(memo.size()-1); ++sum; } if (t == 2) { sum -= app[x]; app[x] = 0; while (not addedTime[x].empty()) { int que = addedTime[x].front(); addedTime[x].pop(); memo[que] = 0; } } if (t == 3) { for (; readtime < x; ++readtime) { app[memo[readtime]]--; if(memo[readtime] != 0) --sum; } } cout << sum << endl; } return 0; }
感想
基本的にはやるだけ… のはずだった WAWAWAWAWA....
C++で書いたけど結構時間ギリギリになってしまった
2完で終わる悲しい結末になった
Undertale ubuntuのsaveファイルの場所
Gルート後、Gルート用のsaveファイルになってしまうらしい
とにかく, saveファイルをリセットしたい時がある
ところで, このゲームすごいストーリーが面白くて、英語が難しい
英語の勉強に使っているのだがかれこれ12時間英語漬け
いい英語の教材を買ったかもしれない
場所は
.config/UNDERTALE_linux_steamver
ABC042 D いろはちゃんとマス目
Question
やること
Abstruct
長方形の通れない場所の右の部分と上の部分の2つに分割して、
の経路の数を, すべてので計算して, sumすればよい。(上下にわけられた長方形の間の移動は, 1通りの経路のみ)
へ移動する経路の数は,
で求めることができる。
これは、 で前処理をしておいて, 後でで求める
その具体的な方法は http://hos.ac/slides/20130319_enumeration.pdf この記事を参照するとわかりやすい.
ここでは深く言及しない。
SourceCode
const int MOD = 1e9 + 7; // x^n % mod // O(log n) template<typename T> T mod_pow(T x, T n, T mod) { T res = 1; while (n > 0) { if (n & 1) res = res * x & mod; x = x*x %mod; n >>= 1; } return res; } // fact(n)%MOD, invFact(n)%MOD, inv(n)%MOD, nCk // Constructor O(N) // other O(1) template<typename T, int MOD> class Choose { public: vector<T> fact, inv, invFact; Choose(T N):fact(N), inv(N), invFact(N){ inv[1] = 1; FOR(i, 2, inv.size()) inv[i] = MOD - (MOD / i) * inv[MOD%i] % MOD; fact[0] = invFact[0] = 1; FOR(i, 1, fact.size()) { fact[i] = fact[i - 1] * i % MOD; invFact[i] = (invFact[i - 1] * inv[i]) % MOD; } } //Get nCk T operator () (T n, T k) const { if (not ((T)0 <= k and k <= n)) return 0; return (((fact[n] * invFact[k]) % MOD)*invFact[n - k]) % MOD; } }; ll f(ll x , ll y, const Choose<ll, MOD>& c) { return c(x + y, x); } signed int main(void) { ll H, W, A, B; cin >> H >> W >> A >> B; Choose<ll, MOD> c(H + W); ll ans = 0; FOR(i, B, W + 1) { ans += f(H - A - 1, i, c) * f(A - 1, W - 1 - i, c); ans %= MOD; } cout << ans << endl; return 0; }
天下一プログラマーコンテスト2016 予選A C問題 山田山本問題
要約
となるように アルファベットの順番を出力する。
アルファベットの順番は辞書順最小のものを出さないといけない
やること
要約
1. AとBを左端から同じ位置にある文字を1文字ずつ比較して違うタイミングでa->bに有向グラフを張る
2. 明示的に、値が小さい方から取り出すトポロジカルソートを使用する.
- A>B and A.size() != B.size() and グラフを貼れなかったとき: -1
- グラフが閉路を含んでいる時: -1
- 辺を張らなかった頂点も, 孤立した単独の頂点として取り扱う。
トポロジカルソート
有向グラフがすべて一方向を向くように、ノードを並べる。
DFSの方法とKhanのアルゴリズムがある。
トポロジカルソート - Wikipedia
memo
- Khanのアルゴリズムを実装
- 今回は, priority_queueでアルファベットが小さい順に取り出していく.
- 辺の削除はコストが掛かりそうなので, 入力辺の数を数えて, 減らしていきながら数を数えた(∵それぞれの辺は一度しか使用されないため)
- max(残りの入力辺の数) != 0 ならば, 閉路がある(-1を出力する。)
SourceCode
#include <iostream> #include <queue> #include <map> #include <list> #include <vector> #include <string> #include <limits> #include <cassert> #include <fstream> #include <cstring> #include <bitset> #include <iomanip> #include <algorithm> #include <functional> #include <cstdio> #include <ciso646> #include <array> #include <cmath> using namespace std; #define FOR(i,a,b) for (int i=(a);i<(b);i++) #define RFOR(i,a,b) for (int i=(b)-1;i>=(a);i--) #define REP(i,n) for (int i=0;i<(n);i++) #define RREP(i,n) for (int i=(n)-1;i>=0;i--) #define inf 0x3f3f3f3f #define uinf 0x3f3f3f3f3f3f3f3f #define CLEAR(a) a = decltype(a)() #define MP make_pair #define ALL(a) (a).begin(),(a).end() #define pii pair<int ,int> #define pcc pair<char,char> #define pic pair<int,char> #define pci pair<char,int> #define VS vector<string> #define VI vector<int> #define VVI vector<vector<int>> #define DEBUG(x) cout<<#x<<": "<<x<<endl #define pi 2*acos(0.0) #define INFILE() freopen("in.txt","r",stdin) #define OUTFILE() freopen("out.txt","w",stdout) #define ll long long #define ull unsigned long long #define eps 1e-14 #define FIN std::ifstream cin("D:\input.txt") const int MOD = 1e9 + 7; // @brief topological sort (Khan's algorithm O(|V|+|E|)) // @param G[node] = {to} (G: adjacency list) // @return sorted values (if G is closed: {}) template<class T> vector<T> tsort(const vector<vector<T> >& G) { vector<T> res; vector<T> in(G.size()); for (auto &node : G) for (auto &to : node) ++in[to]; priority_queue<int, vector<int>, greater<int>> que; REP(i, in.size()) if (in[i] == 0) que.push(i); while (not que.empty()) { int n = que.top(); que.pop(); res.push_back(n); for (auto &to : G[n]) if (--in[to] == 0) que.push(to); } return *max_element(ALL(in)) == 0 ? res : vector<T>(); } signed int main(void) { int N; cin >> N; vector<vector<int> > G('z'-'a'+1); vector<bool> check('z' - 'a' + 1); REP(i, N) { string A, B; cin >> A >> B; int size = min(A.size(), B.size()); bool isPush = false; REP(j,size) { if (A[j] != B[j]) { check[A[j] - 'a'] = true; check[B[j] - 'a'] = true; G[A[j]-'a'].push_back(B[j]-'a'); isPush = true; break; } } if (A > B and A.size() != B.size() and (not isPush)) { cout << -1 << endl; return 0; } } vector<int> res = tsort<int>(G); if (res.size() == 0) cout << -1 << endl; else { for (auto &a : res) cout << (char)(a + 'a'); cout << endl; } return 0; }
ubuntuでterminalを強化したけどいろいろ躓いたメモ
Motivation
後輩がfishを使っていたので、これは便利そうだということで、そろそろterminalを強化してみようと思った
以下を参考に、強化したのだが、いろいろ躓いたところがあるのでメモを残す
各コマンドのチェックはwhichコマンドで
環境 Ubuntu16.04
Content
brewの代わりにaptを使用する.
oh-my-fishのリポジトリが変わっている
現在インストール方法はこう
curl -L https://github.com/oh-my-fish/oh-my-fish/raw/master/bin/install | fish
agnosterfishテーマは,
omf install agnoster
のみで良い
powerline/fontsのリポジトリも変わってる
tmuxは一応ソースビルド
automakeとlibevent-devが必要
sudo apt install automake sudo apt install libevent-dev
入ったらこれ
git clone https://github.com/tmux/tmux sh autogen.sh ./configure && make sudo make install
pecoはaptじゃあ入らない
sudo apt install golang export GOPATH=$HOME/go # .bashrcにも追加しておくこと export PATH=$PATH:$GOROOT/bin # .bashrcにも追加しておくこと go get github.com/peco/peco/cmd/peco fish omf install peco
その他functionなど参考
qiita.com
powerlineも変わってる
sudo apt install python-pip pip install powerline-status==2.4 sudo pip psutil
zコマンドがよくわからない
ubuntuでfish(oh-my-fish導入済み)でz
タイトル通り ubuntuでfishでzコマンドが使いたい
1. z.shを持ってきます。
git clone https://github.com/rupa/z cp z/z.sh /usr/local/bin/
2. z.shのパスを指定
~/.config/fish/config.fish に 以下を追加
set -gx Z_SCRIPT_PATH /usr/local/bin/z.sh
3. omf
omf install z
これでfish上でzコマンドが動きます
4. z-fish (2016-10-29追記)
こいつも導入しておくひつようがあるっぽいです
`git clone`をして, `.config/fish/functions`内に`z.fish`を入れてあげる