codeforces 730 J Bottles

题目链接:https://codeforces.com/contest/730/problem/J

题意:

  给你 n 瓶水,每瓶水量 ai,容量 bi。要将所有水装到尽量少的瓶子内。

  每移动一单位的水要消耗一单位时间,在最少瓶子的前提下,问移动水所需的最短时间。

分析:

  dp

  建立个三维dp[i][j][k] ( 这题刚好可以卡个 1e8 的空间

  ① dp[i][j][k] 表示前 i 个瓶子 , 挑选了 j 个 , 瓶子总容量为 k 时 , 所有瓶子里最大的水量和

  ② dp[i][j][k] 表示前 i 个瓶子 , 挑选了 j 个 , 瓶子总容量为 k 时 , 需花费的最小代价

  这里解释一下②提到的代价:

  每个瓶子只有选和不选两种状态

  选择了的话这个瓶子内的水就不需要移动 , 那么这些水就不会产生代价

  不选的话这个瓶子里的水就需要移动到别的瓶子里 , 那么这些水就会产生代价

做法一:

#include<bits/stdc++.h>
#define ios std::ios::sync_with_stdio(false)
#define rep(i,a,n) for (int i=a;i<=n;i++)
#define mm(a,n) memset(a, n, sizeof(a))
using namespace std;
const int inf (0x3f3f3f3f);
const int N = 1e2 + 1;
struct node{
    int x , y;
    bool operator < (const node & a) const {
        if(y == a.y) return x > a.x;
        return y > a.y;
    }
}a[N];
int dp[N][N][N * N] ;
int pre[N];
int main()
{
    ios;
    int n , sum = 0 , res = 0 , need;
    cin >> n;
    rep(i , 1 , n) cin >> a[i].x , sum += a[i].x;
    rep(i , 1 , n) cin >> a[i].y;
    sort(a + 1 , a + 1 + n);
    rep(i , 1 , n)
    {
        res += a[i].y;
        if(res >= sum)
        {
            need = i ;
            break ;
        }
    }
    mm(dp , -inf);
    rep(i , 1 , n) pre[i] = pre[i - 1] + a[i].y;
    dp[0][0][0] = 0;
    rep(i , 1 , n)
        rep(j , 0 , min(i , need))
            rep(k , 0 , pre[i])
            {
                dp[i][j][k] = dp[i - 1][j][k];
                if(j - 1 >= 0 && k - a[i].y >= 0)
                dp[i][j][k] = max(dp[i][j][k] , dp[i - 1][j - 1][k - a[i].y] + a[i].x);
            }
    int ma = 0;
    rep(i , sum , pre[n]) ma = max(ma , dp[n][need][i]);
    cout << need << " " << sum - ma << ‘\n‘;
    return 0;
}

做法二:

#include<bits/stdc++.h>
#define ios std::ios::sync_with_stdio(false)
#define rep(i,a,n) for (int i=a;i<=n;i++)
#define mm(a,n) memset(a, n, sizeof(a))
using namespace std;
const int inf (0x3f3f3f3f);
const int N = 1e2 + 1;
struct node{
    int x , y;
    bool operator < (const node & a) const {
        if(y == a.y) return x > a.x;
        return y > a.y;
    }
}a[N];
int dp[N][N][N * N] ;
int pre[N];
int main()
{
    ios;
    int n , sum = 0 , res = 0 , need;
    cin >> n;
    rep(i , 1 , n) cin >> a[i].x , sum += a[i].x;
    rep(i , 1 , n) cin >> a[i].y;
    sort(a + 1 , a + 1 + n);
    rep(i , 1 , n)
    {
        res += a[i].y;
        if(res >= sum)
        {
            need = i ;
            break ;
        }
    }
    mm(dp , inf);
    rep(i , 1 , n) pre[i] = pre[i - 1] + a[i].y;
    dp[0][0][0] = 0;
    rep(i , 1 , n)
    {
        rep(j , 0 , min(i , need))
        {
            rep(k , 0 , pre[i])
            {
                dp[i][j][k] = dp[i - 1][j][k] + a[i].x;
                if(j - 1 >= 0 && k - a[i].y >= 0)
                dp[i][j][k] = min(dp[i][j][k] , dp[i - 1][j - 1][k - a[i].y]);
            }
        }
    }
    int ma = inf;
    rep(i , sum , pre[n]) ma = min(ma , dp[n][need][i]);
    cout << need << " " << ma << ‘\n‘;
    return 0;
}

原文地址:https://www.cnblogs.com/StarRoadTang/p/12640391.html

时间: 2024-10-18 05:51:13

codeforces 730 J Bottles的相关文章

【CodeForces】 730J Bottles

传送门 codeforces luogu 题目描述 Nick has n bottles of soda left after his birthday. Each bottle is described by two values: remaining amount of soda ai and bottle volume bi (ai?≤?bi). Nick has decided to pour all remaining soda into minimal number of bottl

【模拟】Codeforces 671A Recycling Bottles

题目链接: http://codeforces.com/problemset/problem/671/A 题目大意: A和B在一张二维平面上,平面上有N个垃圾,垃圾桶只有一个在T,问把所有垃圾全扔进垃圾桶最少走多远.一次只能拿一个垃圾.允许一个人走另一个人停下来. (1 ≤ n ≤ 100 000)  (0 ≤ xi, yi ≤ 109) 题目思路: [模拟] 因为每次只能携带一个垃圾,大部分垃圾都是人扔完上一个垃圾后,从垃圾桶出发去捡的. 而最多有两个垃圾不是被人从垃圾桶出发完再扔到垃圾桶.

CodeForces 671A Recycling Bottles

#pragma comment(linker, "/STACK:1024000000,1024000000") #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #include<vector> #include<map> #include<set> #include<queue> #include&

codeforces 672C - Recycling Bottles 贪心水题

感觉很简单,就是讨论一下 #include <stdio.h> #include <string.h> #include <algorithm> #include <math.h> using namespace std; typedef pair<double,int>pii; const int N = 1e5+5; double x[N],y[N]; pii a[N],b[N]; double dis(double x1,double y1

codeforces GYM 100114 J. Computer Network 无相图缩点+树的直径

题目链接: http://codeforces.com/gym/100114 Description The computer network of “Plunder & Flee Inc.” consists of n servers and m two-way communication links. Two servers can communicate either through a direct link, or through a chain of links, by relayi

codeforces Gym 100187J J. Deck Shuffling dfs

J. Deck Shuffling Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/100187/problem/J Description The world famous scientist Innokentiy continues his innovative experiments with decks of cards. Now he has a deck of n cards and k s

codeforces GYM 100114 J. Computer Network tarjan 树的直径 缩点

J. Computer Network Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/100114 Description The computer network of “Plunder & Flee Inc.” consists of n servers and m two-way communication links. Two servers can communicate either thr

CodeForces 61E Enemy is weak 求i&lt;j&lt;k &amp;&amp; a[i]&gt;a[j]&gt;a[k] 的对数 树状数组

题目链接:点击打开链接 题意是求 i<j<k && a[i]>a[j]>a[k] 的对数 如果只有2元组那就是求逆序数的做法 三元组的话就用一个树状数组x表示 数字i前面有多少个比自己大的个数 然后每次给这个y数组求和,再把x中>a[i]的个数存入y中即可 #include <algorithm> #include <cctype> #include <cassert> #include <cstdio> #in

codeforces Gym 100500 J. Bye Bye Russia

Problem J. Bye Bye RussiaTime Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/100500/attachments Description It was the last day at Russia, after the World Finals has ended. Coach fegla was travelling back to Cairo on the same day b