贪心比较按照哪种买法最优然后全部按照最优买法买即可(有剩余就单独买)
solved
#include <stdio.h> #include <iostream> #include <cstring> #include <algorithm> #include <cmath> #include <queue> #include <map> #include <stack> #include <sstream> #include <set> // #pragma GCC optimize(2) //#define int long long #define rep(i,a,n) for(int i=a;i<=n;i++) #define rush() int T;scanf("%d",&T);for(int Ti=1;Ti<=T;++Ti) #define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); #define mm(i,v) memset(i,v,sizeof i); #define mp(a, b) make_pair(a, b) #define pi acos(-1) #define fi first #define se second //你冷静一点,确认思路再敲!!! using namespace std; typedef long long ll; typedef double db; typedef pair<int, int > PII; priority_queue< PII, vector<PII>, greater<PII> > que; stringstream ssin; // ssin << string while ( ssin >> int) const ll LINF = 0x7fffffffffffffffll; const int N = 4e5 + 5, M = 4e5 + 5, mod = 1e9 + 7, INF = 0x3f3f3f3f; ll _, s, a, b, c; inline ll read() { char c=getchar();ll x=0,f=1; while(c<'0'||c>'9'){if(c=='-')f=-1; c=getchar();} while(c>='0'&&c<='9'){x=x*10+c-'0'; c=getchar();} return x*f; } int main() { // freopen("in.txt","r",stdin); // freopen("out.txt","w",stdout); _ = read(); while (_--) { s = read(); a = read(); b = read(); c = read(); if (1.0 * a * c / (a + b) < c) { ll tmp = s / c; ll ans = tmp / a * b + tmp; cout << ans << ' '; } else { cout << s / c << ' '; } } #ifndef ONLINE_JUDGE system("pause"); #endif }
1065B - Vasya and Isolated Vertices
本题求两问,对于第一问,显然让每天边都匹配两个点是最优的,那么直接输出max(0, n - 2 * m) 即可。
第二问可以直接枚举来得到。
solved
#include <stdio.h> #include <iostream> #include <cstring> #include <algorithm> #include <cmath> #include <queue> #include <map> #include <stack> #include <sstream> #include <set> // #pragma GCC optimize(2) //#define int long long #define rep(i,a,n) for(int i=a;i<=n;i++) #define rush() int T;scanf("%d",&T);for(int Ti=1;Ti<=T;++Ti) #define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); #define mm(i,v) memset(i,v,sizeof i); #define mp(a, b) make_pair(a, b) #define pi acos(-1) #define fi first #define se second //你冷静一点,确认思路再敲!!! using namespace std; typedef long long ll; typedef double db; typedef pair<int, int > PII; priority_queue< PII, vector<PII>, greater<PII> > que; stringstream ssin; // ssin << string while ( ssin >> int) const ll LINF = 0x7fffffffffffffffll; const int N = 4e5 + 5, M = 4e5 + 5, mod = 1e9 + 7, INF = 0x3f3f3f3f; ll n, m; ll ans1, ans2; inline ll read() { char c=getchar();ll x=0,f=1; while(c<'0'||c>'9'){if(c=='-')f=-1; c=getchar();} while(c>='0'&&c<='9'){x=x*10+c-'0'; c=getchar();} return x*f; } bool ck(ll mid) { ll nn = n - mid; if (nn < 0) return false; if (nn == 0) return true; if ((nn * (nn - 1)) / 2 >= m && nn <= 2 * m) return true; return false; } int main() { // freopen("in.txt","r",stdin); // freopen("out.txt","w",stdout); n = read(); m = read(); ans1 = max(0ll, n - 2 * m); ll maxx = 0; for (ll i = 0; i <= n; ++i) { if (i == 0 && m == 0) { maxx = n; break; } if ((i * (i - 1) / 2 >= m && i <= 2 * m)) { maxx = n - i; break; } } ans2 = maxx; cout << ans1 << " " << ans2 << ' '; #ifndef ONLINE_JUDGE system("pause"); #endif }
直接模拟即可
solved
#include <stdio.h> #include <iostream> #include <cstring> #include <algorithm> #include <cmath> #include <queue> #include <map> #include <stack> #include <sstream> #include <set> // #pragma GCC optimize(2) //#define int long long #define rep(i,a,n) for(int i=a;i<=n;i++) #define rush() int T;scanf("%d",&T);for(int Ti=1;Ti<=T;++Ti) #define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); #define mm(i,v) memset(i,v,sizeof i); #define mp(a, b) make_pair(a, b) #define pi acos(-1) #define fi first #define se second //你冷静一点,确认思路再敲!!! using namespace std; typedef long long ll; typedef double db; typedef pair<int, int > PII; priority_queue< PII, vector<PII>, greater<PII> > que; stringstream ssin; // ssin << string while ( ssin >> int) const ll LINF = 0x7fffffffffffffffll; const int N = 4e5 + 5, M = 4e5 + 5, mod = 1e9 + 7, INF = 0x3f3f3f3f; ll n, k; ll a[N]; map<ll, ll>ma; inline ll read() { char c=getchar();ll x=0,f=1; while(c<'0'||c>'9'){if(c=='-')f=-1; c=getchar();} while(c>='0'&&c<='9'){x=x*10+c-'0'; c=getchar();} return x*f; } int main() { // freopen("in.txt","r",stdin); // freopen("out.txt","w",stdout); n = read(); k = read(); ll Min = 1e18, Max = 0; for (int i = 1; i <= n; ++i) { a[i] = read(); ma[a[i]]++; Min = min(Min, a[i]); Max = max(Max, a[i]); } bool flag = 0; ll ans = 1; ll now = Max; ll kk = k; while (now > Min) { if (kk >= ma[now]) { kk -= ma[now]; flag = 1; now--; ma[now] += ma[now + 1]; } else if (kk < ma[now]) { kk = k; ans++; continue; } } if (!flag) ans = 0; cout << ans << ' '; // #ifndef ONLINE_JUDGE // system("pause"); // #endif }
最短路+dp dp[x][y][rep][3][pos] 表示再点(x, y)换了rep次棋后当前使用一个棋子且已经枚举完1-pos位置的最小值
因为是双关键字,可以考虑使用加阈值转化为单关键词或者直接在dp方程式中表示
unsolved
#include <stdio.h> #include <iostream> #include <cstring> #include <algorithm> #include <cmath> #include <queue> #include <map> #include <stack> #include <sstream> #include <set> // #pragma GCC optimize(2) //#define int long long #define rep(i,a,n) for(int i=a;i<=n;i++) #define rush() int T;scanf("%d",&T);for(int Ti=1;Ti<=T;++Ti) #define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); #define mm(i,v) memset(i,v,sizeof i); #define mp(a, b) make_pair(a, b) #define pi acos(-1) #define fi first #define se second using namespace std; typedef long long ll; typedef double db; typedef pair<int, int > PII; priority_queue< PII, vector<PII>, greater<PII> > que; stringstream ssin; // ssin << string while ( ssin >> int) const ll LINF = 0x7fffffffffffffffll; const int M = 4e5 + 5, mod = 1e9 + 7, INF = 0x3f3f3f3f; int n, N; int MAP[15][15]; int nx[8] = {-1, -2, -2, -1, 1, 2, 2, 1}; int ny[8] = {-2, -1, 1, 2, 2, 1, -1, -2}; int dp[15][15][205][4][105]; inline ll read() { char c=getchar();ll x=0,f=1; while(c<'0'||c>'9'){if(c=='-')f=-1; c=getchar();} while(c>='0'&&c<='9'){x=x*10+c-'0'; c=getchar();} return x*f; } struct node { int x, y, cost, repl, now, num; bool operator<(const node &a) const { return cost > a.cost; } // friend bool operator < (node a,node b){ // return a.cost > b.cost; // } }s, e; bool check(node u) { if (u.x >= 1 && u.x <= n && u.y >= 1 && u.y <= n && dp[u.x][u.y][u.repl][u.now][u.num] > u.cost) return true; return false; } bool ck(int x, int y) { if (x < 1 || x > n || y < 1 || y > n) return false; return true; } void solve() { priority_queue<node>q; mm(dp, 0x3f); dp[s.x][s.y][0][0][1] = 0; dp[s.x][s.y][0][1][1] = 0; dp[s.x][s.y][0][2][1] = 0; q.push({s.x, s.y, 0, 0, 0, 1}); q.push({s.x, s.y, 0, 0, 1, 1}); q.push({s.x, s.y, 0, 0, 2, 1}); while (!q.empty()) { node u = q.top(); q.pop(); if (dp[u.x][u.y][u.repl][u.now][u.num] < u.cost) continue; if (u.repl > 200) continue; node h; // 判断换子 for (int i = 0; i < 3; ++i) { if (i == u.now) continue; h = u; h.repl++; h.now = i; h.cost++; if (!check(h)) continue; dp[h.x][h.y][h.repl][h.now][h.num] = h.cost; q.push(h); } if (u.now == 0) { //骑士垂直走 for (int i = 1; i <= n; ++i) { if (u.x == i) continue; h = u; h.x = i; h.cost++; if (h.num + 1 == MAP[h.x][h.y]) h.num++; if (!check(h)) continue; dp[h.x][h.y][h.repl][h.now][h.num] = h.cost; q.push(h); } for (int i = 1; i <= n; ++i) { if (u.y == i) continue; h = u; h.y = i; h.cost++; if (h.num + 1 == MAP[h.x][h.y]) h.num++; if (!check(h)) continue; dp[h.x][h.y][h.repl][h.now][h.num] = h.cost; q.push(h); } } else if (u.now == 1) { // 马走日字 for (int i = 0; i < 8; ++i) { int xx = u.x + nx[i], yy = u.y + ny[i]; if (xx < 1 || xx > n || yy < 1 || yy > n) continue; h = u; h.x = xx; h.y = yy; h.cost ++; if (h.num + 1 == MAP[h.x][h.y]) h.num++; if (!check(h)) continue; dp[h.x][h.y][h.repl][h.now][h.num] = h.cost; q.push(h); } } else if (u.now == 2) { // 象走斜线 for (int i = 1; i <= n; ++i) { // -1, -1 int xx = u.x + i * (-1), yy = u.y + i * (-1); if (!ck(xx, yy)) break; h = u; h.cost++; h.x = xx; h.y = yy; if (h.num + 1 == MAP[h.x][h.y]) h.num++; if (!check(h)) continue; dp[h.x][h.y][h.repl][h.now][h.num] = h.cost; q.push(h); } for (int i = 1; i <= n; ++i) { // -1, 1 int xx = u.x + i * (-1), yy = u.y + i * 1; if (!ck(xx, yy)) break; h = u; h.cost++; h.x = xx; h.y = yy; if (h.num + 1 == MAP[h.x][h.y]) h.num++; if (!check(h)) continue; dp[h.x][h.y][h.repl][h.now][h.num] = h.cost; q.push(h); } for (int i = 1; i <= n; ++i) { // 1, -1 int xx = u.x + i * 1, yy = u.y + i * (-1); if (!ck(xx, yy)) break; h = u; h.cost++; h.x = xx; h.y = yy; if (h.num + 1 == MAP[h.x][h.y]) h.num++; if (!check(h)) continue; dp[h.x][h.y][h.repl][h.now][h.num] = h.cost; q.push(h); } for (int i = 1; i <= n; ++i) { // 1, 1 int xx = u.x + i * 1, yy = u.y + i * 1; if (!ck(xx, yy)) break; h = u; h.cost++; h.x = xx; h.y = yy; if (h.num + 1 == MAP[h.x][h.y]) h.num++; if (!check(h)) continue; dp[h.x][h.y][h.repl][h.now][h.num] = h.cost; q.push(h); } } } int Min = 1e9, u = 0; for (int i = 0; i <= 200; ++i) { for (int j = 0; j < 3; ++j) { if (dp[e.x][e.y][i][j][n * n] < Min) { Min = dp[e.x][e.y][i][j][n * n]; u = i; } } } printf("%d %d ", Min, u); } int main() { // freopen("in.txt","r",stdin); // freopen("out.txt","w",stdout); n = read(); N = n; for (int i = 1; i <= n; ++i) { for (int j = 1; j <= n; ++j) { int x; x = read(); MAP[i][j] = x; if (x == 1) { s.x = i; s.y = j; } else if (x == n * n) { e.x = i; e.y = j; } } } solve(); // #ifndef ONLINE_JUDGE // system("pause"); // #endif }