1、HDU 3486
题意:
n个人组成的序列,每一个元素有一个权值,现在要将这n个数分成m段(不能整除的去掉),
且要求这m段每段的最大值相加求和结果>K。求最小的M。
数据范围:N<=2e5,K<=1e9,Vi>=0。
思路:
首先明确m越小,也就是每个组的人数尽可能的多。我们可以枚举M,
然后求解当前M下所获得的权值之和并与K相比较,如果符合要求,直接break,
否则,进入下一层循环的M。M的最小值==K/序列中权值的最大值,M<=2e5,
时间复杂度O(M*M*LogN)。时间复杂度好高的样子,不过大部分题解都是这
样鸭。
2、HDU 3193
题意:
n个元素,每个元素由两个权值构成,
问这n个元素中有几个元素满足没有其他元素
严格小于它。(N<=1e4)
思路:
显然可以按照某一个权值排序,然后遍历这n个元素,对于每一个元素,
二分找他前面权值first比他小(没有等于)的最后一个数,然后从找到的这个
数往前的区间内做RMQ找最小值,看是不是比当前判断的数的小。没啥东西
,,,应该能做出来吧。
AC代码(状态不好?WA了这么多次,心不静)
#include <cstdlib>
#include <iostream>
#include<algorithm>
#include <set>
#include <queue>
#include <stack>
#include<vector>
#include<map>
#include<ctime>
#include<cmath>
/** -?£- **/
#define LL long long
#define par pair<int,int>
#define INF 0x3f3f3f3f
#define io ios::sync_with_stdio(false)
using namespace std;
const int N=2e5+100;
const int M=4e6+100;
par a[N];
bool cmp(par xx,par yy)
{
if(xx.first==yy.first)return xx.second<yy.second;
return xx.first<yy.first;
}
int dp[N][35];
int search(int x,int y)
{
int t=log(y-x+1)/log(2);
return min(dp[x][t],dp[y-(1<<t)+1][t]);
}
par ans[N];
int tot;
int main()
{
int n;
while(cin>>n)
{
tot=0;
for(int i=1;i<=n;++i)cin>>a[i].first>>a[i].second;
sort(a+1,a+1+n,cmp);
for(int i=1;i<=n;++i)dp[i][0]=a[i].second;
int t1=log(n)/log(2)+1;
for(int j=1;j<t1;++j)
for(int i=1;i+(1<<j)-1<=n;++i)//模板敲错好几遍
{
dp[i][j]=min(dp[i][j-1],dp[i+(1<<(j-1))][j-1]);
}
int mini=INF;
for(int i=1;i<=n;++i)
{
if(i==1)
{
ans[++tot].first=a[i].first;
ans[tot].second=a[i].second;
continue;
}
int l=1,r=i;
int index=1;
while(l<=r)//脑子有点乱,这地方没想清楚,,,
{
int mid=(l+r)/2;
if(a[mid].first==a[i].first)r=mid-1,index=mid;
else if(a[mid].first<a[i].first)l=mid+1;
else r=mid-1;
}
if(index==1)
{
ans[++tot].first=a[i].first;
ans[tot].second=a[i].second;
continue;
}
else index-=1;
//cout<<i<<" "<<index<<endl;
int tmp=search(1,index);
if(a[i].second<=tmp)
{
ans[++tot].first=a[i].first;
ans[tot].second=a[i].second;
}
}
cout<<tot<<endl;
sort(ans+1,ans+1+tot,cmp);
for(int i=1;i<=tot;i++)cout<<ans[i].first<<" "<<ans[i].second<<endl;
}
return 0;
}
3、HDU - 2888(二维RMQ)
题意:子矩阵的最值问题,二维RMQ模板。
4、HDU - 3183(思维题)
题意:N个数(N<=1000),从中去掉m个数,使得剩余的数组成的数最小。
思路:
贪心就不说了,找ai>ai+1的情况。
RMQ的话也没啥好说的,想不到没法做,,,做积累:
最后n-m个数组成的序列中第一个元素一定在原序列1~m+1
中出现,以此类推不断找最小值。为什么?鬼知道。
,,,,,,