标签:codeforces 贪心 暴力 stl
You are given an n?×?m rectangular table consisting of lower case English letters. In one operation you can completely remove one column from
the table. The remaining parts are combined forming a new table. For example, after removing the second column from the table
abcd
edfg
hijk
we obtain the table:
acd
efg
hjk
A table is called good if its rows are ordered from top to bottom lexicographically, i.e. each row is lexicographically no larger than the following one. Determine the minimum number of operations
of removing a column needed to make a given table good.
Output
Print a single number — the minimum number of columns that you need to remove in order to make the table good.
Note
In the first sample the table is already good.
In the second sample you may remove the first and third column.
In the third sample you have to remove all the columns (note that the table where all rows are empty is considered good by definition).
Let strings s and t have equal length. Then, s is lexicographically
larger than t if they are not equal and the character following the largest common prefix of s and t (the
prefix may be empty) in s is alphabetically larger than the corresponding character of t.
贪心。
我们可以发现从左往右扫,当前能取的列就一定要取,取了不会更差,只会更好。
什么是能取的列?
在之前所有取好的列中,如果每一列这一行,下一行。。。都相同,那么当前这列的这几行必须满足不减性质,否则任意。
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <string>
#define mp make_pair
#define f first
#define s second
using namespace std;
pair<int,int> q[10000],qq[10000];
int n,m,f[105],cnt;
string s[105];
int main()
{
scanf("%d%d",&n,&m);
for (int i=1;i<=n;i++)
cin>>s[i];
int ans=0;
cnt=1;
q[1]=mp(1,n);
for (int i=0;i<m;i++)
{
int ok=1;
for (int j=1;j<=cnt;j++)
{
for (int k=q[j].f+1;k<=q[j].s;k++)
if (s[k][i]<s[k-1][i]) ok=0;
if (!ok) break;
}
if (ok)
{
ans++;
for (int j=1;j<=cnt;j++)
qq[j]=q[j];
int c=0;
for (int j=1;j<=cnt;j++)
{
int l=qq[j].f;
for (int k=qq[j].f+1;k<=qq[j].s;k++)
{
if (s[k][i]!=s[k-1][i])
{
if (k!=l+1)
{
q[++c]=mp(l,k-1);
}
l=k;
}
}
if (l!=qq[j].s)
q[++c]=mp(l,qq[j].s);
}
cnt=c;
}
}
cout<<m-ans<<endl;
return 0;
}
对于一个t来说,s是唯一的,因此我们可以枚举t,然后判断多少回合会赢。
记录第k个1/2出现的位置,以及到每个位置共有1几个1和几个2出现过。
只要判断谁先得到t分就知道这一回合谁赢了,往后枚举即可。
这样看起来很暴力,但是n/1+n/2+n/3+n/4+......的复杂度是O(nlogn)的!
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <cstring>
#define mp make_pair
#define inf 0x3f3f3f3f
#define M 200005
using namespace std;
int s1[M],s2[M],x[M],p1[M],p2[M],n;
pair<int,int> ans[M];
int Judge(int t)
{
int k1=0,k2=0,now=0;
while (now<n)
{
if (p1[s1[now]+t]<p2[s2[now]+t])
k1++,now=p1[s1[now]+t];
else k2++,now=p2[s2[now]+t];
if (now>n) return 0;
}
if (k1>k2) return k1;
return 0;
}
int main()
{
scanf("%d",&n);
for (int i=1;i<=n;i++)
scanf("%d",&x[i]);
memset(p1,127,sizeof(p1));
memset(p2,127,sizeof(p2));
if (x[n]==2)
for (int i=1;i<=n;i++)
x[i]=3-x[i];
int n1=0,n2=0;
for (int i=1;i<=n;i++)
{
if (x[i]==1) p1[++n1]=i;
else p2[++n2]=i;
s1[i]=n1,s2[i]=n2;
}
int cnt=0;
for (int i=1;i<=n;i++)
{
int k=Judge(i);
if (k)
ans[++cnt]=mp(k,i);
}
sort(ans+1,ans+1+cnt);
cout<<cnt<<endl;
for (int i=1;i<=cnt;i++)
printf("%d %d\n",ans[i].first,ans[i].second);
return 0;
}
贪心+STL。
这题也要想的清清楚楚再写。。
(以下l表示下界,r表示上界)
我们首先把part和actor都按照l排序,枚举part,然后把所有l不大于这个part的l都插入set中,贪心的选择r大于等于这个part的r的最小r,然后k--,如果这个actor的k=0,那么从set中除去。
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cmath>
#include <set>
#define mp make_pair
using namespace std;
set<pair<int,int> > s;
set<pair<int,int> >::iterator it;
int n,m,ans[100005];
struct data
{
int l,r,k,id;
}a[100005],b[100005];
bool cmp(data a,data b)
{
if (a.l==b.l)
return a.r<b.r;
return a.l<b.l;
}
int main()
{
scanf("%d",&n);
for (int i=1;i<=n;i++)
a[i].id=i,scanf("%d%d",&a[i].l,&a[i].r);
scanf("%d",&m);
for (int i=1;i<=m;i++)
b[i].id=i,scanf("%d%d%d",&b[i].l,&b[i].r,&b[i].k);
sort(a+1,a+1+n,cmp);
sort(b+1,b+1+m,cmp);
int j=1;
for (int i=1;i<=n;i++)
{
for (;j<=m&&b[j].l<=a[i].l;j++)
s.insert(mp(b[j].r,j));
it=s.lower_bound(mp(a[i].r,0));
if (it==s.end())
{
puts("NO");
return 0;
}
int x=it->second;
ans[a[i].id]=b[x].id;
b[x].k--;
if (!b[x].k)
s.erase(mp(b[x].r,x));
}
cout<<"YES"<<endl;
cout<<ans[1];
for (int i=2;i<=n;i++)
cout<<" "<<ans[i];
cout<<endl;
return 0;
}
【codeforces #283(div 1)】ABC题解
标签:codeforces 贪心 暴力 stl
原文地址:http://blog.csdn.net/regina8023/article/details/44249203