CSP模拟赛#4 - T4 蜗牛老师的积木总结

分析1:由于说不一定所有的积木都要用(dfs大法好)可以确定用dfs去搜

而且还要保证上面的要被下面的完全覆盖

所以我们暴力枚举每条边做长和宽即可(裸的dfs,没一点优化)

然后我们就得到了40分的代码

#include <bits/stdc++.h>
using namespace std;
const int MAXN = 20;
int n,ans=0;bool f[MAXN];
struct node
{
    int a,b,c;
}a[MAXN];
void dfs(int x,int y,int sum)
{
    ans=max(ans,sum);
    for(int i=1;i<=n;i++)
    {
        if(!f[i])  //如果没搜过
        //逐个枚举
        {
            if(a[i].a<=x&&a[i].b<=y)
            {
                f[i]=true;
                dfs(a[i].a,a[i].b,sum+a[i].c);
                f[i]=false;
            }
            if(a[i].b<=x&&a[i].a<=y)
            {
                f[i]=true;
                dfs(a[i].b,a[i].a,sum+a[i].c);
                f[i]=false;
            }
            if(a[i].a<=x&&a[i].c<=y)
            {
                f[i]=true;
                dfs(a[i].a,a[i].c,sum+a[i].b);
                f[i]=false;
            }
            if(a[i].c<=x&&a[i].a<=y)
            {
                f[i]=true;
                dfs(a[i].c,a[i].a,sum+a[i].b);
                f[i]=false;
            }
            if(a[i].b<=x&&a[i].c<=y)
            {
                f[i]=true;
                dfs(a[i].b,a[i].c,sum+a[i].a);
                f[i]=false;
            }
            if(a[i].a<=x&&a[i].b<=y)
            {
                f[i]=true;
                dfs(a[i].c,a[i].b,sum+a[i].a);
                f[i]=false;
            }
        }
    }
}
int main()
{
    freopen("brick.in","r",stdin);
    freopen("brick.out","w",stdout);
    ios::sync_with_stdio(false);
    cin>>n;
    for(int i=1;i<=n;i++)
        cin>>a[i].a>>a[i].b>>a[i].c;
    for(int i=1;i<=n;i++)
    {
        f[i]=1;
        dfs(a[i].a,a[i].b,a[i].c);
        dfs(a[i].b,a[i].c,a[i].a);
        dfs(a[i].a,a[i].c,a[i].b);
        f[i]=0;   //回溯
    }
    cout<<ans;
    return 0;
}
结果惨不忍睹(毕竟没优化

 让我们再来考虑一下有没有哪里可以优化的地方(第一次自闭中

这里的dfs是逐个枚举,那我们其实可以分为选和不选,只要选的那一个满足条件就行,不需要写那么多一个个枚举  

满心欢喜的交了,只拿了30分(qwq

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN = 20;
ll n,ans,cnt;
bool f[MAXN];
struct node
{
    ll a,b,c,index;  //长宽高和编号
}a[MAXN];
bool cmp(node a,node b)
{
    if(a.a!=b.a) return a.a>b.a;
    else return a.b>b.b;
}
void dfs(ll now,ll sum,ll x,ll y)  //now编号,sum高度,x,y表示下面层的长宽
{
    ans=max(ans,sum);
    if(now==cnt+1) return;
    dfs(now+1,sum,x,y);  //当前这个不选
    if(!f[a[now].index]&&a[now].a<=x&&a[now].b<=y) //当前这个选
    {
        f[a[now].index]=true;
        dfs(now+1,sum+a[now].c,a[now].a,a[now].b);
        f[a[now].index]=false;
    }
}
int main()
{
    freopen("brick.in","r",stdin);
    freopen("brick.out","w",stdout);
    ios::sync_with_stdio(false);
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        int x,y,z;
        cin>>x>>y>>z;
        a[++cnt]=(node){max(x,y),min(x,y),z,i};
        a[++cnt]=(node){max(x,z),min(x,z),y,i};
        a[++cnt]=(node){max(y,z),min(y,z),x,i};
    }
    sort(a+1,a+1+n,cmp);
    dfs(1,0,1e8,1e8);
    cout<<ans;
    return 0;
}

 更是惨不忍睹(4种情况就很nice

   哎,分析一下吧(高强度自闭中) 

  1. N范围虽然<=15​,可是每一个​i都有它的长宽,长高,宽高为底面

    那么一共有多少种情况呢?

    N<=15,每一个i​都有​3种情况,所以一共是15*3=45​种情况

    而数组只开到​20,所以会出现​MLE

  2. sort范围搞错,一共有​cnt种情况,但是只排序到​n

  3. 选择条件应添加if(a[now].a>=a[now].b)(.a表示长,.b表示宽),否则不能确定长宽要与哪个比较(​x还是y)

改过终于100了(太难了,一道dfs交了十几遍—)

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN = 1010;
ll n,ans=LONG_LONG_MIN,cnt,f[1010],Sum[1010];
struct node
{
    ll a,b,c,index;
}a[1010];
bool cmp(node x,node b)
{
    if(x.a!=b.a) return x.a>b.a;
    else return x.b>b.b;
}
void dfs(ll now,ll sum,ll x,ll y)
{
    if(now==cnt+1)
    {
        ans=max(ans,sum);
        return;
    }
    dfs(now+1,sum,x,y);  //当前这个不选
    if(f[a[now].index]==0&&a[now].a<=x&&a[now].b<=y&&a[now].a>=a[now].b) //当前这个选
    {
        f[a[now].index]=1;
        dfs(now+1,sum+(long long)a[now].c,a[now].a,a[now].b);
        f[a[now].index]=0;
    }
}
int main()
{
    freopen("brick.in","r",stdin);
    freopen("brick.out","w",stdout);
    cin>>n;int x,y,z;
    for(int i=1;i<=n;i++)
    {
        cin>>x>>y>>z;
        a[++cnt]=(node){max(x,y),min(x,y),z,i};
        a[++cnt]=(node){max(x,z),min(x,z),y,i};
        a[++cnt]=(node){max(y,z),min(y,z),x,i};
    }
    sort(a+1,a+1+cnt,cmp);
    dfs(1,0,1e8,1e8);
    cout<<ans; 
    return 0;
}

AC!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值