計算一下能夠達到水是多少,能夠到達的糖是多少
枚舉水,而後加最多能加的糖,是\(min(F - i *100,E * 100)\),計算密度,和前一個比較就行node
#include <bits/stdc++.h> #define fi first #define se second #define pii pair<int,int> #define mp make_pair #define pb push_back #define space putchar(' ') #define enter putchar('\n') #define MAXN 100005 #define eps 1e-12 //#define ivorysi using namespace std; typedef long long int64; typedef unsigned int u32; typedef double db; template<class T> void read(T &res) { res = 0;T f = 1;char c = getchar(); while(c < '0' || c > '9') { if(c == '-') f = -1; c = getchar(); } while(c >= '0' && c <= '9') { res = res * 10 + c - '0'; c = getchar(); } res *= f; } template<class T> void out(T x) { if(x < 0) {x = -x;putchar('-');} if(x >= 10) { out(x / 10); } putchar('0' + x % 10); } int A,B,C,D,E,F; int w[35],t[3005]; void Solve() { read(A);read(B);read(C);read(D);read(E);read(F); w[0] = 1; for(int i = 1 ; i <= F / 100 ; ++i) { if(i >= A) w[i] |= w[i - A]; if(i >= B) w[i] |= w[i - B]; } t[0] = 1; for(int i = 1 ; i <= F ; ++i) { if(i >= C) t[i] |= t[i - C]; if(i >= D) t[i] |= t[i - D]; } t[0] = 0; for(int i = 1 ; i <= F ; ++i) { if(t[i]) t[i] = i; else t[i] = t[i - 1]; } int a = A * 100,b = 0; for(int i = 1 ; i <= F / 100 ; ++i) { if(!w[i]) continue; int rem = min(F - i * 100,i * E); int s = t[rem],p = i * 100 + s; if(s * a > b * p) {a = p;b = s;} } out(a);space;out(b);enter; } int main() { #ifdef ivorysi freopen("f1.in","r",stdin); #endif Solve(); }
很容易發現邊確定都被涵蓋在最短路的數值裏(若是要構造出一個價值最小的圖)c++
咱們從小到大加邊,對於一個(u,v)最短路,若是這個最短路不用額外邊,那麼就是用一個別的點k,(u,k) + (k,v) = (u,v)chrome
若是算出來的最短路小於給定值,那麼就不合法spa
#include <bits/stdc++.h> #define fi first #define se second #define pii pair<int,int> #define mp make_pair #define pb push_back #define space putchar(' ') #define enter putchar('\n') #define MAXN 100005 #define eps 1e-12 //#define ivorysi using namespace std; typedef long long int64; typedef unsigned int u32; typedef double db; template<class T> void read(T &res) { res = 0;T f = 1;char c = getchar(); while(c < '0' || c > '9') { if(c == '-') f = -1; c = getchar(); } while(c >= '0' && c <= '9') { res = res * 10 + c - '0'; c = getchar(); } res *= f; } template<class T> void out(T x) { if(x < 0) {x = -x;putchar('-');} if(x >= 10) { out(x / 10); } putchar('0' + x % 10); } int64 A[305][305]; int64 B[305][305],ans; pii p[100005]; int tot,N; void Solve() { read(N); for(int i = 1 ; i <= N ; ++i) { for(int j = 1 ; j <= N ; ++j) { read(A[i][j]); if(i != j) B[i][j] = 1e16; if(i < j) p[++tot] = mp(i,j); } } sort(p + 1,p + tot + 1,[](pii a,pii b){return A[a.fi][a.se] < A[b.fi][b.se];}); for(int i = 1 ; i <= tot ; ++i) { int u = p[i].fi,v = p[i].se; for(int j = 1 ; j <= N ; ++j) { B[u][v] = min(B[u][j] + B[j][v],B[u][v]); } B[v][u] = B[u][v]; if(B[u][v] < A[u][v]) {puts("-1");return;} if(B[u][v] == A[u][v]) continue; ans += A[u][v]; B[u][v] = B[v][u] = A[u][v]; } out(ans);enter; } int main() { #ifdef ivorysi freopen("f1.in","r",stdin); #endif Solve(); }
咱們但願除了和該點同色的值以外,另外一種顏色的值總和儘量的小,這樣容易達成目標
能夠直接作一個揹包dp就行,每次儘可能取最小的值當作另外一種顏色的值rest
#include <bits/stdc++.h> #define fi first #define se second #define pii pair<int,int> #define mp make_pair #define pb push_back #define space putchar(' ') #define enter putchar('\n') #define MAXN 5005 #define eps 1e-12 //#define ivorysi using namespace std; typedef long long int64; typedef unsigned int u32; typedef double db; template<class T> void read(T &res) { res = 0;T f = 1;char c = getchar(); while(c < '0' || c > '9') { if(c == '-') f = -1; c = getchar(); } while(c >= '0' && c <= '9') { res = res * 10 + c - '0'; c = getchar(); } res *= f; } template<class T> void out(T x) { if(x < 0) {x = -x;putchar('-');} if(x >= 10) { out(x / 10); } putchar('0' + x % 10); } int N,P[MAXN],X[MAXN]; int dp[MAXN],sum[MAXN]; bool f[MAXN][MAXN]; void Solve() { read(N); for(int i = 2 ; i <= N ; ++i) read(P[i]); for(int i = 1 ; i <= N ; ++i) read(X[i]); for(int i = 1 ; i <= N ; ++i) f[i][0] = 1; for(int i = N ; i >= 1 ; --i) { bool flag = 0; for(int j = X[i] ; j >= 0 ; --j) { if(f[i][j]) { dp[i] = sum[i] - j; flag = 1; break; } } if(!flag) { puts("IMPOSSIBLE");return; } if(P[i]) { for(int j = X[P[i]] ; j >= 0 ; --j) { bool t = 0; if(j >= X[i]) t |= f[P[i]][j - X[i]]; if(j >= dp[i]) t |= f[P[i]][j - dp[i]]; f[P[i]][j] = t; } sum[P[i]] += X[i] + dp[i]; } } puts("POSSIBLE"); } int main() { #ifdef ivorysi freopen("f1.in","r",stdin); #endif Solve(); }
行列拆點,有一個點就行列之間連邊code
連出的圖確定是不少個基環外向樹森林rem
至關於給每一個點分配一個邊,給環上的點分配邊就兩種方式,每種分別計算方案數get
分配完以後每一個點假如橫向,這個點往橫向以前全部的點連一條邊
豎向同理it
而後就是求一個樹的dfs序個數class
最後把全部聯通塊的答案合出來就行
#include <bits/stdc++.h> #define fi first #define se second #define pii pair<int,int> #define mp make_pair #define pb push_back #define space putchar(' ') #define enter putchar('\n') #define MAXN 200005 #define eps 1e-12 //#define ivorysi using namespace std; typedef long long int64; typedef unsigned int u32; typedef double db; template<class T> void read(T &res) { res = 0;T f = 1;char c = getchar(); while(c < '0' || c > '9') { if(c == '-') f = -1; c = getchar(); } while(c >= '0' && c <= '9') { res = res * 10 + c - '0'; c = getchar(); } res *= f; } template<class T> void out(T x) { if(x < 0) {x = -x;putchar('-');} if(x >= 10) { out(x / 10); } putchar('0' + x % 10); } const int MOD = 1000000007; int inc(int a,int b) { return a + b >= MOD ? a + b - MOD : a + b; } int mul(int a,int b) { return 1LL * a * b % MOD; } int fpow(int x,int c) { int res = 1,t = x; while(c) { if(c & 1) res = mul(res,t); t = mul(t,t); c >>= 1; } return res; } void update(int &x,int y) { x = inc(x,y); } struct node { int to,next; }E[MAXN * 4]; int x[MAXN],y[MAXN],N,fac[MAXN],invfac[MAXN]; map<pii,int> zz; int head[MAXN],sumE; bool vis[MAXN]; int sum,Ncnt,fa[MAXN],s,t,pos[MAXN],par[MAXN]; vector<int> c[MAXN],r[MAXN],rec,cyc; int rpos[MAXN],cpos[MAXN],siz[MAXN]; vector<int> son[MAXN]; void add(int u,int v) { E[++sumE].to = v; E[sumE].next = head[u]; head[u] = sumE; } pii depos(int a,int b) { if(a > b) swap(a,b); b -= N; return mp(a,b); } bool dfs(int u) { ++Ncnt; bool flag = 0; vis[u] = 1; for(int i = head[u] ; i ; i = E[i].next) { ++sum; int v = E[i].to; if(!vis[v]) { fa[v] = u; if(dfs(v)) { flag = 1; pos[zz[depos(u,v)]] = u; } } else if(v != fa[u] && !flag){ s = u,t = v; flag = 1; rec.pb(zz[depos(u,v)]); } } if(!flag && fa[u]) { pos[zz[depos(u,fa[u])]] = u; } if(fa[u]) rec.pb(zz[depos(u,fa[u])]); return flag; } int Calc(int u) { siz[u] = 1; int res = 1; for(auto v : son[u]) { res = mul(res,Calc(v)); res = mul(res,invfac[siz[v]]); siz[u] += siz[v]; } res = mul(res,fac[siz[u] - 1]); return res; } int Process() { int res = 0; for(auto t : rec) par[t] = 0; for(auto t : rec) { if(pos[t] > N) { for(int i = 0 ; i < cpos[t] ; ++i) { par[zz[mp(c[y[t]][i],y[t])]] = t; } } else { for(int i = 0 ; i < rpos[t] ; ++i) { par[zz[mp(x[t],r[x[t]][i])]] = t; } } son[t].clear(); } son[0].clear(); for(auto t : rec) { son[par[t]].pb(t); } return Calc(0); } void Solve() { read(N); for(int i = 1 ; i <= 2 * N ; ++i) { read(x[i]);read(y[i]);add(x[i],y[i] + N);add(y[i] + N,x[i]); zz[mp(x[i],y[i])] = i; r[x[i]].pb(y[i]);c[y[i]].pb(x[i]); } for(int i = 1 ; i <= N ; ++i) { sort(r[i].begin(),r[i].end()); sort(c[i].begin(),c[i].end()); for(int j = 1 ; j < r[i].size() ; ++j) rpos[zz[mp(i,r[i][j])]] = j; for(int j = 1 ; j < c[i].size() ; ++j) cpos[zz[mp(c[i][j],i)]] = j; } fac[0] = 1; for(int i = 1 ; i <= 2 * N ; ++i) fac[i] = mul(fac[i - 1],i); invfac[2 * N] = fpow(fac[2 * N],MOD - 2); for(int i = 2 * N - 1 ; i >= 0 ; --i) invfac[i] = mul(invfac[i + 1],i + 1); int ans = fac[2 * N]; for(int i = 1 ; i <= 2 * N ; ++i) { if(!vis[i]) { sum = 0;Ncnt = 0; rec.clear(); dfs(i); ans = mul(ans,invfac[Ncnt]); if(Ncnt * 2 != sum) {puts("0");return;} int p = s; cyc.clear(); while(1) { cyc.pb(p); if(p == t) break; p = fa[p]; } int tmp = 0; cyc.pb(s); for(int i = 0 ; i < cyc.size() - 1 ; ++i) { pos[zz[depos(cyc[i],cyc[i + 1])]] = cyc[i]; } update(tmp,Process()); for(int i = cyc.size() - 1 ; i >= 1 ; --i) { pos[zz[depos(cyc[i],cyc[i - 1])]] = cyc[i]; } update(tmp,Process()); ans = mul(ans,tmp); } } out(ans);enter; } int main() { #ifdef ivorysi freopen("f1.in","r",stdin); #endif Solve(); }