数模组搜索训练题

明显比ACM的搜索简单许多~许多~许多……

https://vjudge.net/contest/336728#overview

A、B、D很基本;

C题是个贪心

可以将w按降序排列,则只考虑 l 即可,每次选取与当前 l 差值最小的 l2放在l的后面; 

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

bool vis[10001];
struct hh
{
    int w,l;
}a[10001];

bool cmp(hh a,hh b)
{
    if(a.w == b.w) return a.l > b.l;
    else return a.w > b.w;
}

void solve()
{
    int n;
    int ans = 0;
    cin >> n;
    for(int i = 1; i <= n; i++)
    {
        cin >> a[i].w >> a[i].l;
        vis[i] = 0;
    }
    sort(a + 1,a + n + 1,cmp);
    for(int i = 1;i <= n;i ++)
    {
        int Max = a[i].l;
        if(vis[i]) continue;
        vis[i] = 1;
        for(int  j = i + 1;j <= n;j ++)
        {
            if(a[j].l <= Max && !vis[j])
            {
                vis[j] = 1;
                Max = a[j].l;
            }
        }
        ans ++;
    }
    cout << ans << endl;
} 

int main()
{
    int T;
    cin >> T;
    while(T --)
    solve();
    return 0;
}

E:

这是个好题;

优化;

1、简化状态,从下往上堆叠正方形,记录每列的高度;

2、先放大的,再放小的,而且尽量把一个正方形放在它当前能放的最佳位置(恰好放入或者放入后留的空间尽量小)

3、正方形的边长很小,可以直接用数组记录数量(数据范围);

http://poj.org/problem?id=1020

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int T,x,s,n,summ;
int cake[15],sum[50];

bool dfs(int k)
{
	if(k == n) return true;
	int Min = 2146,pos = 0;
	for(int i = 1;i <= s;i ++)
		if(Min > sum[i])
			Min = sum[i],pos = i;
	for(int i = 10;i >= 1;i --)
	{
		if(!cake[i] || i + pos - 1 > s || i + Min > s) continue;
		int flag = 1;
		for(int j = pos;j <= i + pos - 1;j ++)
		{
			if(sum[j] != Min)//能放入,高度必须齐平
			{
				flag = 0;
				break;
			}
		}
		if(flag)
		{
			cake[i] --;
			for(int j = pos;j <= i + pos - 1;j ++) sum[j] += i;
			if(dfs(k + 1)) return true;
			for(int j = pos;j <= i + pos - 1;j ++) sum[j] -= i;
			cake[i] ++;
		}
	}
	return false;
}

void solve()
{
	summ = 0;
	memset(cake,0,sizeof(cake));
	memset(sum,0,sizeof(sum));
	cin >> s >> n;
	for(int i = 1; i <= n;i ++) 
	{
		cin >> x;
		summ += x * x;
		cake[x] ++;
	}
	if(summ == s * s && dfs(0))
		cout << "KHOOOOB!" << "\n";
	else 	
		cout << "HUTUTU!" << "\n";
	return;
}

int main()
{
	cin >> T;
	while(T --)
	solve();
	return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值