2024 暑假友谊赛 1

096 - Cooking

#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编辑  收藏  举报

导航