F-Partition problem
https://ac.nowcoder.com/acm/contest/882/F
题意:输入一个数n,代表总共有2n个人,然后每个人对所有人有个贡献值,然后问题需要将2n个人分成两组,每组n个人,问如何分组使得两组之间的价值最大,同组人不算价值。
思路:直接dfs暴力分组。
//aeha
#include<bits/stdc++.h>
using namespace std;
typedef long long int ll;
typedef unsigned long long int ull;
const int inf = 0x3f3f3f3f;
int dir[8][2]={{1,0},{0,1},{1,1},{1,-1},{-1,1},{-1,-1},{0,-1},{-1,0}};
#define pi acos(-1)
#define ls rt<<1
#define rs rt<<1|1
#define me0(s) memset(s,0,sizeof(s))
#define me1(s) memset(s,1,sizeof(s))
#define mef(s) memset(s,-1,sizeof(s))
#define meinf(s) memset(s,inf,sizeof(s))
const int N=105;
ll ans;
int n;
int t1[30],t2[30];
int a[N],b[N],v[N][N];
inline int read() {
char c=getchar(); int x=0, f=1;
while(c<'0'|c>'9') {if(c=='-') f=-1;c=getchar();}
while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
return x*f;
}
ll q_pow(ll a,ll b,ll mod){
ll anss=1;
while(b){
if(b&1) anss=anss*a%mod;
a=a*a%mod;
b>>=1;
}
return anss;
}
ll q_mul(ll a,ll b,ll mod){
ll anss=0;
while(b){
if(b&1) anss=(anss+a)%mod;
a=(a+a)%mod;
b>>=1;
}
return anss;
}
void dfs(int pos,int cnt1,int cnt2,ll ret){
// pos表示当前搜的人的序号,cnt1表示第一组的人数,cnt2表示第二组的人数,ret表示贡献
if(cnt1==cnt2&&cnt1==n){
ans=max(ans,ret);
return ;
}
ll tmp=0;
if(cnt1<n){
for(int i=0;i<cnt2;i++){
tmp+=v[pos][t2[i]];
}
t1[cnt1]=pos;
dfs(pos+1,cnt1+1,cnt2,ret+tmp);
}
tmp=0;
if(cnt2<n){
for(int i=0;i<cnt1;i++){
tmp+=v[pos][t1[i]];
}
t2[cnt2]=pos;
dfs(pos+1,cnt1,cnt2+1,ret+tmp);
}
}
int main(int argc, char * argv[])
{
std::ios::sync_with_stdio(false);
cin>>n;
ans=0;
for(int i=0;i<2*n;i++){
for(int j=0;j<2*n;j++){
cin>>v[i][j];
}
}
dfs(0,0,0,0);
cout<<ans<<endl;
return 0;
}
H-Second Large Rectangle
https://ac.nowcoder.com/acm/contest/882/H
题意:给定一个n*m的矩阵,其中全由0,1两个数字组成,问找到的第二大的全由1组成的矩阵的面积是多少。
思路:先用单调栈的求第一大矩阵的模板,然后在后面的时候修改一下 ,将各种状态保存下来,注意去重。然后输出第二大的面积就行。
#include<bits/stdc++.h>
using namespace std;
typedef long long int ll;
typedef unsigned long long int ull;
const int inf = 0x3f3f3f3f;
#define pi acos(-1)
#define ls rt<<1
#define rs rt<<1|1
#define me0(s) memset(s,0,sizeof(s))
#define me1(s) memset(s,1,sizeof(s))
#define mef(s) memset(s,-1,sizeof(s))
#define meinf(s) memset(s,inf,sizeof(s))
const int N=1005;
char a[2060][2060];
int h[2060];
int L[2060],R[2060];
map<int,int> ma;
bool v[1005][1005];
inline int read() {
char c=getchar(); int x=0, f=1;
while(c<'0'|c>'9') {if(c=='-') f=-1;c=getchar();}
while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
return x*f;
}
ll q_pow(ll a,ll b,ll mod){
ll anss=1;
while(b){
if(b&1) anss=anss*a%mod;
a=a*a%mod;
b>>=1;
}
return anss;
}
ll q_mul(ll a,ll b,ll mod){
ll anss=0;
while(b){
if(b&1) anss=(anss+a)%mod;
a=(a+a)%mod;
b>>=1;
}
return anss;
}
int main(int argc, char * argv[])
{
std::ios::sync_with_stdio(false);
int n,m;
while(cin>>n>>m){
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
cin>>a[i][j];
}
}
int maxn=0;
for(int i=1;i<=n;i++){
me0(v);
for(int j=1;j<=m;j++){
if(a[i][j]=='1')
h[j]++;
else h[j]=0;
}
h[0]=h[m+1]=-1;
stack<int>s;
for(int j=1;j<=m;j++){
L[j]=0;
if(s.size()==0){
s.push(j);
L[j]=j;
}
else{
while(s.size()>0&&h[s.top()]>=h[j])
s.pop();
if(s.size()==0) L[j]=1;
else L[j]=s.top()+1;
s.push(j);
}
}
while(!s.empty()){
s.pop();
}
for(int j=m;j>=1;j--){
R[j]=m;
if(s.size()==0){
s.push(j);R[j]=j;
}
else{
while(s.size()>0&&h[s.top()]>=h[j])s.pop();
if(s.size()==0)R[j]=m;
else R[j]=s.top()-1;
s.push(j);
}
}
for(int j=1;j<=m;j++){
if(!v[L[j]][R[j]]){
ma[h[j]*(R[j]-L[j]+1)]++;
v[L[j]][R[j]]=1;
ma[h[j]*(R[j]-L[j])]++;
ma[(h[j]-1)*(R[j]-L[j]+1)]++;
}
if(h[j]*(R[j]-L[j]+1)>maxn)
maxn=h[j]*(R[j]-L[j]+1);
}
}
int flag=0,ans,pos;
for(int i=maxn;i>=0;i--){
if(ma[i]&&ma[i]>1){
ans=i;
flag=1;
break;
}
else if(ma[i]&&ma[i]==1){
pos=i;
break;
}
}
if(flag) cout<<ans<<endl;
else{
for(int i=pos-1;i>=0;i--){
if(ma[i]){
ans=i;
break;
}
}
cout<<ans<<endl;
}
}
return 0;
}