洛谷 P3040 [USACO12JAN]贝尔分享Bale Share

P3040 [USACO12JAN]贝尔分享Bale Share

题目描述

Farmer John has just received a new shipment of N (1 <= N <= 20) bales of hay, where bale i has size S_i (1 <= S_i <= 100). He wants to divide the bales between his three barns as fairly as possible.

After some careful thought, FJ decides that a "fair" division of the hay bales should make the largest share as small as possible. That is, if B_1, B_2, and B_3 are the total sizes of all the bales placed in barns 1, 2, and 3, respectively (where B_1 >= B_2 >= B_3), then FJ wants to make B_1 as small as possible.

For example, if there are 8 bales in these sizes:

2 4 5 8 9 14 15 20

A fair solution is

Barn 1: 2 9 15   B_1 = 26
Barn 2: 4 8 14   B_2 = 26
Barn 3: 5 20     B_3 = 25
Please help FJ determine the value of B_1 for a fair division of the hay bales. 

FJ有N (1 <= N <= 20)包干草,干草i的重量是 S_i (1 <= S_i <= 100),他想尽可能平均地将干草分给3个农场。

他希望分配后的干草重量最大值尽可能地小,比如, B_1,B_2和 B_3是分配后的三个值,假设B_1 >= B_2 >= B_3,则他希望B_1的值尽可能地小。

例如:8包干草的重量分别是:2 4 5 8 9 14 15 20,一种满足要求的分配方案是

农场 1: 2 9 15 B_1 = 26

农场 2: 4 8 14 B_2 = 26

农场 3: 5 20 B_3 = 25

请帮助FJ计算B_1的值。

输入输出格式

输入格式:

  • Line 1: The number of bales, N.
  • Lines 2..1+N: Line i+1 contains S_i, the size of the ith bale.

输出格式:

  • Line 1: Please output the value of B_1 in a fair division of the hay bales.

输入输出样例

输入样例#1: 复制

8
14
2
5
15
8
9
20
4

输出样例#1: 复制

26 

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define MAXN 30
using namespace std;
int n;
int A,B,C;
int ans=0x7f7f7f7fl;
int sum[MAXN];
void dfs(int now){
    if(max(A,max(B,C))>ans)    return ;
    if(now==n+1){
        ans=max(A,max(C,B));
        return;
    }
    A+=sum[now];dfs(now+1);A-=sum[now];
    B+=sum[now];dfs(now+1);B-=sum[now];
    C+=sum[now];dfs(now+1);C-=sum[now];
}
int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
        scanf("%d",&sum[i]);
    dfs(1);
    cout<<ans;
}

60分的dfs

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define MAXN 30
using namespace std;
int n;
int A,B,C;
int ans=0x7f7f7f7fl;
int sum[MAXN];
void dfs(int now){
    if(now==n+1){
        ans=max(A,max(C,B));
        return;
    }
    A+=sum[now];if(A<ans)    dfs(now+1);A-=sum[now];
    B+=sum[now];if(B<ans)    dfs(now+1);B-=sum[now];
    C+=sum[now];if(C<ans)    dfs(now+1);C-=sum[now];
}
int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
        scanf("%d",&sum[i]);
    dfs(1);
    cout<<ans;
}

AC的dfs

正解思路:动态规划。

f[i][j][k]表示到第i堆干草为止,第一个农场分到j的干草,第二个农场分到k的干草。

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define MAXN 10010
using namespace std;
int n;
int dp[23][2010][2010];
int num[MAXN],sum[MAXN];
int dfs(int now,int x,int y){
    int z=sum[now-1]-x-y;
    if(now==n+1)    return max(x,max(y,z));
    if(dp[now][x][y])    return dp[now][x][y];
    dp[now][x][y]=min(dfs(now+1,x+num[now],y),min(dfs(now+1,x,y+num[now]),dfs(now+1,x,y)));
    return dp[now][x][y];
}
int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++)    scanf("%d",&num[i]);
    for(int i=1;i<=n;i++)    sum[i]=sum[i-1]+num[i];
    dfs(1,0,0);
    cout<<dp[1][0][0];
}
时间: 2024-10-07 10:26:22

洛谷 P3040 [USACO12JAN]贝尔分享Bale Share的相关文章

P3040 [USACO12JAN]贝尔分享Bale Share

想了一个二分 + 状压的思路, 嫌太麻烦了, 直接一个dfs + 最优性剪枝水了过去. 貌似比某些dp还快? #include <cstdio> #include <cstring> #include <cassert> #include <iostream> #include <algorithm> using namespace std; const int MAXN = 20 + 2; inline int read(){ char ch

洛谷P3043 [USACO12JAN]牛联盟Bovine Alliance

P3043 [USACO12JAN]牛联盟Bovine Alliance 题目描述 Bessie and her bovine pals from nearby farms have finally decided that they are going to start connecting their farms together by trails in an effort to form an alliance against the farmers. The cows in each

洛谷 P1561 [USACO12JAN]爬山Mountain Climbing

传送门 题目大意: n头牛,上山时间为u(i),下山为d(i). 要求每一时刻最多只有一头牛上山,一头牛下山. 问每头牛都上下山后花费最少时间. 题解:贪心 推了推样例,发现上山时间一定,那找个下山最快 的当最后一头山上的牛. #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define LL long long #define N 25009 using

洛谷—— P1561 [USACO12JAN]爬山Mountain Climbing

https://daniu.luogu.org/problemnew/show/P1561 题目描述 Farmer John has discovered that his cows produce higher quality milk when they are subject to strenuous exercise. He therefore decides to send his N cows (1 <= N <= 25,000) to climb up and then back

洛谷 P3041 [USACO12JAN] Video Game Combos

题目描述 Bessie is playing a video game! In the game, the three letters 'A', 'B', and 'C' are the only valid buttons. Bessie may press the buttons in any order she likes; however, there are only N distinct combos possible (1 <= N <= 20). Combo i is repr

在洛谷3369 Treap模板题 中发现的Splay详解

本题的Splay写法(无指针Splay超详细) 前言 首先来讲...终于调出来了55555...调了整整3天..... 看到大部分大佬都是用指针来实现的Splay.小的只是按照Splay的核心思想和原理来进行的.可能会有不妥之处,还请大佬们指出,谢谢! 那么这个题解存在的意义就是让不会敲Splay的人额...会敲Splay啦... 基本思想 数据结构 对于Splay,我定义了一个class类(当成struct就行啦...个人习惯不同啦),定义名称为“Splay”. 之后在类中,我定义了Splay

洛谷P4180 [Beijing2010组队]次小生成树Tree(最小生成树,LCT,主席树,倍增LCA,倍增,树链剖分)

洛谷题目传送门 %%%天平巨佬和山楠巨佬%%% 他们的题解 思路分析 具体思路都在两位巨佬的题解中.这题做法挺多的,我就不对每个都详细讲了,泛泛而谈吧. 首先kruskal把最小生成树弄出来,因为要求次小生成树.至于为什么次小一定只在最小的基础上改变了一条边,我也不会证......打表找规律大法好 剩下的可以有一堆数据结构来维护最大值和次大值(原理两位巨佬都讲清楚了,这里只分析一下算法的优劣) 倍增+LCA 山楠巨佬的做法,我也写了这一种.复杂度\(O(MlogM(kruscal)+MlogN(

洛谷 P2709 BZOJ 3781 小B的询问

题目描述 小B有一个序列,包含N个1~K之间的整数.他一共有M个询问,每个询问给定一个区间[L..R],求Sigma(c(i)^2)的值,其中i的值从1到K,其中c(i)表示数字i在[L..R]中的重复次数.小B请你帮助他回答询问. 输入输出格式 输入格式: 第一行,三个整数N.M.K. 第二行,N个整数,表示小B的序列. 接下来的M行,每行两个整数L.R. 输出格式: M行,每行一个整数,其中第i行的整数表示第i个询问的答案. 输入输出样例 输入样例#1: 6 4 3 1 3 2 1 1 3

洛谷1231 教辅的组成

洛谷1231 教辅的组成 https://www.luogu.org/problem/show?pid=1231 题目背景 滚粗了的HansBug在收拾旧语文书,然而他发现了什么奇妙的东西. 题目描述 蒟蒻HansBug在一本语文书里面发现了一本答案,然而他却明明记得这书应该还包含一份练习题.然而出现在他眼前的书多得数不胜数,其中有书,有答案,有练习册.已知一个完整的书册均应该包含且仅包含一本书.一本练习册和一份答案,然而现在全都乱做了一团.许多书上面的字迹都已经模糊了,然而HansBug还是可