SDUTACM20级集训队2022春季选拔赛--1 补题(ICPC North America Qualifier Contest 2015 D、G)
Circuit Counting
题意:
给定\(N\)个点的坐标,问有多少个非空子序列的点的横坐标累加、纵坐标累加后为\((0,0)\)
思路:
定义\(dp(i,x,y)\)为前\(i\)个坐标横坐标、纵坐标累加为\((x,y)\)的子序列个数
此时不选当前点\(dp(i,x,y)=dp(i-1,x,y)\)
选这个点\(dp(i,x,y)+=dp(i-1,x-a[i].x,y-a[i].y)\)
由于坐标有负数的情况,所以把负数映射到正数,把(500,500)定位原点,其他点都按照这个来平移映射
最后删掉空集的情况
#include <bits/stdc++.h>
using namespace std;
const int N = 1111;
#define ll long long
#define x first
#define y second
typedef pair<int, int> PII;
ll dp[2][N][N];
int n;
PII a[N];
signed main() {
cin >> n;
for (int i = 1, x, y; i <= n; i++) {
cin >> x >> y;
a[i] = {x, y};
}
dp[0][500][500] = 1ll;
for (int i = 1; i <= n; i++) {
for (int x = 0; x <= 1000; x++) {
for (int y = 0; y <= 1000; y++) {
dp[i & 1][x][y] = dp[(i & 1) ^ 1][x][y];
if (x - a[i].x >= 0 && y - a[i].y >= 0)
dp[i & 1][x][y] += dp[(i & 1) ^ 1][x - a[i].x][y - a[i].y];
}
}
}
cout << dp[n & 1][500][500] - 1 << endl;
}
Safe Passage
题意:
现在给\(N\)个人使用道具返回家的时间,只有一个道具,道具最多可以两个人共用,当两个人共用道具回家时,回家时间取决于慢的一方,现在问把\(N\)个人都送回家,最少需要多长时间
思路:
两种贪心策略
1.先让两个最快的回家,再让最快的回来,再让最慢的两个回家,再让第二快的回来,时间就是\(a_2+a_1+a_{now}+a_2\)
2.让最快的带着最慢的两人依次回家,时间就是\(a_{now}+a_{now-1}+a_1+a_1\)
每次取min就行,人数\(≤3\)时特判即可
#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 10;
int a[N];
int n;
int main() {
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> a[i];
}
sort(a + 1, a + n + 1);
if (n <= 2) {
cout << max(a[1], a[2]) << endl;
return 0;
}
int res = 0;
int now = n;
while (now) {
if (now == 1) {
res += a[now];
now -= 1;
} else if (now == 2) {
res += max(a[now - 1], a[now]);
now -= 2;
} else if (now == 3) {
res += a[1] + a[2] + a[3];
now -= 3;
} else {
res += min(2 * a[2] + a[1] + a[now], 2 * a[1] + a[now] + a[now - 1]);
now -= 2;
}
}
cout << res << endl;
}

浙公网安备 33010602011771号