USACO 4.1.2 栅栏的木料

这个讲的超好....一定要看...然后看我代码就好懂啦...

http://blog.csdn.net/ta201314/article/details/41287567

各种优化确实非常好....搜索的一道好题...

挂代码:

/*
    Problem : USACO 4.1.2 栅栏的木料
    Author : Robert Yuan

    优化解释:
    0. 二分+贪心判断可行解 (根据自己设计的贪心算法尽量的得到一个比较靠近正确值的 ans,再后面的搜索的下界就会大大提高)
    1. 如果使用的木料与上一块的木料大小相同,那么上一块若没有选前 i块木板,这一块也不要选(1.若是因为前面的太小而不选,那么对于这个也太小  2.若是因为前面的情况已经搜过,那我选择前面的就成了一个已经搜索过的情况)
    2. 如果当前需要枚举的木板与上一块木板的大小相同,只选其中最后的那块,理由同上。
    3. 如果剩下的木板大小比第一块还小,那么就是属于余料,将所有余料和已经切好的木料减去,剩下的木板长度如果比未切好的 x个木料总长还要小,那么这种状态也是不可行的
*/

#include<cstdio>
#include<cstring>
#include<algorithm>

using namespace std;

inline int in(){
    int x=0;char ch=getchar();
    while(ch>‘9‘ || ch<‘0‘) ch=getchar();
    while(ch>=‘0‘ && ch<=‘9‘) x=x*10+ch-‘0‘,ch=getchar();
    return x;
}

const int maxn=52;
const int maxm=1025;
const int INF=0x7f7f7f7f;

int n,m,S,ans;
int tmp[maxn];
int a[maxn],b[maxm],s[maxm];

bool cmp(const int &a,const int &b){
    return a>b;
}

bool dfs(int x,int last){
    if(!x) return true;
    if(S<s[x]) return false;/*优化 3*/
    S-=b[x];
    for(int i= x!=ans && b[x]==b[x+1] ? last:1/*优化 1*/;i<=n;i++){
        while(i<n && a[i]==a[i+1]) i++;/*优化 2*/
        if(a[i]>=b[x]){
            a[i]-=b[x];
            if(a[i]<b[1]) S-=a[i];
            if(dfs(x-1,i)){
                if(a[i]<b[1]) S+=a[i];
                a[i]+=b[x];    S+=b[x];
                return true;
            }
            if(a[i]<b[1]) S+=a[i];
            a[i]+=b[x];
        }
    }
    S+=b[x];
    return false;
}

bool check(int m){/*优化 0*/
    int Minn,Minx;
    memcpy(tmp,a,sizeof(a));
    for(int i=m;i;i--){
        Minn=INF,Minx=-1;
        for(int j=1;j<=n;j++)
            if(tmp[j]>=b[i] && Minn>tmp[j])
                Minn=tmp[j],Minx=j;
        if(Minx<0) return false;
        tmp[Minx]-=b[i];
    }
    return true;
}

int main(){
    n=in();
    for(int i=1;i<=n;i++) a[i]=in(),S+=a[i];
    m=in();
    for(int i=1;i<=m;i++) b[i]=in();

    sort(a+1,a+n+1);
    sort(b+1,b+m+1);

    for(int i=1;i<=m;i++)
        s[i]=s[i-1]+b[i];

    int l=0,r=m,mid;

    if(check(r)){
        printf("%d",m);return 0;
    }

    while(l+1<r){
        mid=(l+r)>>1;
        if(check(mid)) l=mid;
        else r=mid;
    }
    ans=r;
    while(dfs(ans,1) && ans<=m) ans++;
    printf("%d",ans-1);

    return 0;
}

时间: 2024-10-11 09:04:39

USACO 4.1.2 栅栏的木料的相关文章

codevs2777 栅栏的木料

题目描述 Description 农民John准备建一个栅栏来围住他的牧场.他已经确定了栅栏的形状,但是他在木料方面有些问题.当地的杂货储存商扔给John一些木板,而John必须从这些木板中找出尽可能多所需的木料. 当然,John可以切木板.因此,一个9英尺的木板可以切成一个5英尺和一个4英尺的木料 (当然也能切成3个3英尺的,等等).John有一把(完美的)梦之锯,因此他在切木料时,不会有木料的损失. 所需要的栅栏长度可能会有重复(比如,一个3英尺和另一个3英尺长的栅栏可能同时都需要).所需要

codevs 2039 骑马修栅栏 USACO x

我承认我是转的@自为风月马前卒 嘿~ 题目描述 Description Farmer John每年有很多栅栏要修理.他总是骑着马穿过每一个栅栏并修复它破损的地方. John是一个与其他农民一样懒的人.他讨厌骑马,因此从来不两次经过一个栅栏.你必须编一个程序,读入栅栏网络的描述,并计算出一条修栅栏的路径,使每个栅栏都恰好被经过一次.John能从任何一个顶点(即两个栅栏的交点)开始骑马,在任意一个顶点结束. 每一个栅栏连接两个顶点,顶点用1到500标号(虽然有的农场并没有500个顶点).一个顶点上可

洛谷P2731 骑马修栅栏 Riding the Fences

P2731 骑马修栅栏 Riding the Fences• o 119通过o 468提交• 题目提供者该用户不存在• 标签USACO• 难度普及+/提高 提交 讨论 题解 最新讨论 • 数据有问题题目背景Farmer John每年有很多栅栏要修理.他总是骑着马穿过每一个栅栏并修复它破损的地方.题目描述John是一个与其他农民一样懒的人.他讨厌骑马,因此从来不两次经过一个栅栏.你必须编一个程序,读入栅栏网络的描述,并计算出一条修栅栏的路径,使每个栅栏都恰好被经过一次.John能从任何一个顶点(即

洛谷P1519 穿越栅栏 Overfencing

P1519 穿越栅栏 Overfencing 69通过 275提交 题目提供者该用户不存在 标签USACO 难度普及/提高- 提交  讨论  题解 最新讨论 USACO是100分,洛谷是20分 为什么只有十分 题目描述 描述 农夫John在外面的田野上搭建了一个巨大的用栅栏围成的迷宫.幸运的是,他在迷宫的边界上留出了两段栅栏作为迷宫的出口.更幸运的是,他所建造的迷宫是一个“完美的”迷宫:即你能从迷宫中的任意一点找到一条走出迷宫的路.给定迷宫的宽度W(1<=W<=38)及高度H(1<=H&

2039 骑马修栅栏

2039 骑马修栅栏 USACO 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description Farmer John每年有很多栅栏要修理.他总是骑着马穿过每一个栅栏并修复它破损的地方. John是一个与其他农民一样懒的人.他讨厌骑马,因此从来不两次经过一个栅栏.你必须编一个程序,读入栅栏网络的描述,并计算出一条修栅栏的路径,使每个栅栏都恰好被经过一次.John能从任何一个顶点(即两个栅栏的交点)开始骑马,在任意一个顶点结束. 每一个栅

洛谷P2731骑马修栅栏

题目背景 Farmer John每年有很多栅栏要修理.他总是骑着马穿过每一个栅栏并修复它破损的地方. 题目描述 John是一个与其他农民一样懒的人.他讨厌骑马,因此从来不两次经过一个栅栏.你必须编一个程序,读入栅栏网络的描述,并计算出一条修栅栏的路径,使每个栅栏都恰好被经过一次.John能从任何一个顶点(即两个栅栏的交点)开始骑马,在任意一个顶点结束. 每一个栅栏连接两个顶点,顶点用1到500标号(虽然有的农场并没有500个顶点).一个顶点上可连接任意多(>=1)个栅栏.两顶点间可能有多个栅栏.

USACO 6.3 Fence Rails(一道纯剪枝应用)

Fence RailsBurch, Kolstad, and Schrijvers Farmer John is trying to erect a fence around part of his field. He has decided on the shape of the fence and has even already installed the posts, but he's having a problem with the rails. The local lumber s

USACO翻译:USACO 2013 DEC Silver三题

USACO 2013 DEC SILVER 一.题目概览 中文题目名称 挤奶调度 栅栏油漆 奶牛排队 英文题目名称 msched paint lineup 可执行文件名 msched paint lineup 输入文件名 msched.in paint.in lineup.in 输出文件名 msched.out paint.out lineup.out 每个测试点时限 1秒 1秒 1秒 测试点数目 10 10 10 每个测试点分值 10 10 10 比较方式 全文比较 全文比较 全文比较 二.运

USACO翻译:USACO 2012 JAN三题(1)

USACO 2012 JAN(题目一) 一.题目概览 中文题目名称 礼物 配送路线 游戏组合技 英文题目名称 gifts delivery combos 可执行文件名 gifts delivery combos 输入文件名 gifts.in delivery.in combos.in 输出文件名 gifts.out delivery.out combos.out 每个测试点时限 1秒 1秒 1秒 测试点数目 10 10 10 每个测试点分值 10 10 10 比较方式 全文比较 全文比较 全文比