2024 暑假友谊赛 1
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define pii pair<int, int>
int main()
{
ios::sync_with_stdio(0), cin.tie(0);
int n,sum=0;
//要让花的时间尽量少,也就是我们要尽量的把时间分配到两个烤炉当中
//然后再去取这两个当中较大的值,如果是贪心的思考,局部最优无法代表全局最优比如3 3 3 4 5
//而我们只需要对一个烤炉去列举所有的情况,即取i个物品可以达到的体积的情况
//再通俗点就是 取1个物品的所有体积情况,2个物品的所有体积情况,3个物品所有的体积情况.......
//然后再遍历这些所有的情况找到与sum差值最小的就是答案
cin>>n;
int a[105];
for(int i=1;i<=n;i++) cin>>a[i],sum+=a[i];
bool dp[105][100005];//一个烤炉,取i个可以达到的体积情况,按题意来就是花时间的情况
dp[1][0]=1;
for(int i=1;i<=n;i++)
for(int j=0;j<=sum;j++)
{
if(dp[i][j]){
dp[i+1][j]=1;
dp[i+1][j+a[i]]=1;
}
}
int ans=sum;
for(int i=1;i<=sum;i++)
{
if(dp[n][i]){//全部的菜都被选了以后,花时间的情况
ans=min(ans,max(i,sum-i));
}
}
cout<<ans<<endl;
}
C - 2D Plane 2N Points
1.这一题是二分图最大匹配的模版题,只需要通过两层循环,把符合x1<x2,y1<y2的点放进去,相当于点和点在建立边,然后套模版输出即可
#include <bits/stdc++.h>
#define int long long
#define endl '\n'
using namespace std;
typedef pair<int,int> pii;
#define x first
#define y second
#define all(v) v.begin(),v.end()
#define allr(v) v.rbegin(),v.rend()
int dx[]={0,1,-1,0};
int dy[]={-1,0,0,1};
struct augment_path {
vector<vector<int> > g;
vector<int> pa; // 匹配
vector<int> pb;
vector<int> vis; // 访问
int n, m; // 两个点集中的顶点数量
int dfn; // 时间戳记
int res; // 匹配数
augment_path(int _n, int _m) : n(_n), m(_m) {
assert(0 <= n && 0 <= m);
pa = vector<int>(n, -1);
pb = vector<int>(m, -1);
vis = vector<int>(n);
g.resize(n);
res = 0;
dfn = 0;
}
void add(int from, int to) {
assert(0 <= from && from < n && 0 <= to && to < m);
g[from].push_back(to);
}
bool dfs(int v) {
vis[v] = dfn;
for (int u : g[v]) {
if (pb[u] == -1) {
pb[u] = v;
pa[v] = u;
return true;
}
}
for (int u : g[v]) {
if (vis[pb[u]] != dfn && dfs(pb[u])) {
pa[v] = u;
pb[u] = v;
return true;
}
}
return false;
}
int solve() {
while (true) {
dfn++;
int cnt = 0;
for (int i = 0; i < n; i++) {
if (pa[i] == -1 && dfs(i)) {
cnt++;
}
}
if (cnt == 0) {
break;
}
res += cnt;
}
return res;
}
};
signed main()
{
ios::sync_with_stdio(0),cin.tie(0);
int n;cin>>n;
pii a[105],b[105];
for(int i=0;i<n;i++) cin>>a[i].x>>a[i].y;
for(int i=0;i<n;i++) cin>>b[i].x>>b[i].y;
augment_path ans(n,n);//存边
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
if(a[i].x<b[j].x&&a[i].y<b[j].y) ans.add(i,j);//把合法的点存入,相当于图中的点建立边
}
}
cout<<ans.solve()<<endl;//结果
return 0;
}
posted on 2024-07-18 16:49 swj2529411658 阅读(8) 评论(0) 编辑 收藏 举报