把B排序一遍,然后记忆化搜索一下
用
fx,y,k,z
表示a数组中第x个零,枚举到
b[y]+k
,且
ai>aj
的点对
(i,j)
有z个的情况是否可行,这样数组大小是50*50*50*2500的,
bitset存一下就好了…
没打过这么暴力的程序
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <vector>
#include <cmath>
#include <bitset>
#include <assert.h>
using namespace std;
bitset<50*50> vis[55][55][55];
bool ap[55][105];
class KingdomAndDice{
int n,tot,lim,ss,ans;
vector<int> c;
void dfs(int x,int y,int k,int cur){
if(abs(2*ans-tot)>abs(2*cur-tot)) ans=cur;
else if(abs(2*ans-tot)==abs(2*cur-tot) && ans>cur) ans=cur;
if(x>n) return ;
if(y>=c.size()) return ;
if(c[y]+k>lim) return ;
if(vis[x][y][k][cur]) return ;
vis[x][y][k][cur]=1;
if(y+1!=c.size() && c[y]+k==c[y+1]) return dfs(x,y+1,1,cur);
if(y+1<c.size()) dfs(x,y+1,1,cur);
if(ap[y][k]){
if(y+1==c.size() || c[y]+k+1<c[y+1]) dfs(x,y,k+1,cur);
return ;
}
if(y+1==c.size() || c[y]+k+1<c[y+1]) dfs(x+1,y,k+1,cur+y);
else dfs(x+1,y+1,1,cur+y);
}
public:
double newFairness(vector<int> a,vector<int> b,int x){
int cur=0; tot=a.size()*b.size(); n=0; ans=tot; lim=x;
for(int i=0;i<a.size();i++){
if(!a[i]){
n++; continue;
}
for(int j=0;j<b.size();j++){
if(a[i]>b[j]) cur++;
}
}
b.push_back(0);
sort(b.begin(),b.end()); c=b;
for(int i=0;i<a.size();i++)
for(int j=0;j<b.size();j++)
if(a[i]-b[j]>0 && a[i]-b[j]<=50) ap[j][a[i]-b[j]]=1;
//for(int i=0;i<b.size();i++) printf("%d ",b[i]); putchar('\n');
dfs(1,0,0,cur);
return (double)ans/tot;
}
};