明显比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;
}