[DP] TopCoder SRM548 Div1 450. KingdomAndDice

把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;
  }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值