n很小
可以暴搜所有情况
合法性用上下界网络流判断
// BEGIN CUT HERE
// END CUT HERE
#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <queue>
#include <assert.h>
#include <cstring>
using namespace std;
const int N=1010,inf=1<<29;
int n,a[N],h[N],hst;
vector<int> c[N];
int u[N*N],d[N*N],adj[N*N],ans[750],t;
namespace flow{
int cnt,S,T,ss,tt,G[N],dis[N],cur[N];
struct edge{
int t,nx,f;
}E[N<<1];
inline void addedge(int x,int y,int f){
E[++cnt].t=y; E[cnt].nx=G[x]; G[x]=cnt; E[cnt].f=f;
E[++cnt].t=x; E[cnt].nx=G[y]; G[y]=cnt; E[cnt].f=0;
}
queue<int> Q;
inline bool bfs(){
while(!Q.empty()) Q.pop();
for(int i=0;i<=tt;i++) dis[i]=-1;
dis[ss]=0; Q.push(ss);
while(!Q.empty()){
int x=Q.front(); Q.pop();
for(int i=G[x];i;i=E[i].nx)
if(E[i].f && !~dis[E[i].t]){
dis[E[i].t]=dis[x]+1;
if(E[i].t==tt) return true;
Q.push(E[i].t);
}
}
return false;
}
int dfs(int x,int f){
if(x==tt || !f) return f;
int used=0,w;
for(int &i=cur[x];i;i=E[i].nx)
if(E[i].f && dis[E[i].t]==dis[x]+1){
w=dfs(E[i].t,min(f-used,E[i].f));
E[i].f-=w; E[i^1].f+=w;
if((used+=w)==f) return f;
}
if(!used) dis[x]=-1;
return used;
}
inline bool check(){
S=0; T=n+n+1; ss=T+1; tt=ss+1; cnt=1;
int nf=0;
for(int i=0;i<=tt;i++) G[i]=0;
for(int i=1;i<=n;i++){
addedge(i,tt,a[i]);
addedge(ss,i+n,a[i]);
nf+=a[i];
}
for(int i=0;i<c[1].size();i++) addedge(S,c[1][i],inf);
for(int i=1;i<=n;i++) addedge(i+n,T,inf);
for(int i=1;i<=t;i++)
if(adj[i]){
addedge(ss,u[i],1); addedge(d[i]+n,tt,1); addedge(d[i]+n,u[i],inf);
nf++;
}
addedge(T,S,inf);
while(bfs()){
for(int i=0;i<=tt;i++) cur[i]=G[i];
nf-=dfs(ss,inf);
}
return !nf;
}
}
int cur,cv[N],lst[N],vis[N];
inline void calc(){
for(int i=1;i<=n;i++) cv[i]=0;
for(int i=1;i<=t;i++)
if(adj[i]) cv[d[i]]|=1<<u[i];
for(int i=1;i<=n;i++){
int x=lst[i];
if(cv[x]) return ;
for(int j=1;j<=t;j++)
if(adj[j] && u[j]==x) cv[d[j]]^=1<<x;
}
cur++;
}
void lfs(int x){
if(x>n) return calc();
for(int i=1;i<=n;i++)
if(!vis[i]){
vis[i]=1; lst[x]=i; lfs(x+1); vis[i]=0;
}
}
void check(){
if(!flow::check()) return ;
cur=0; lfs(1); ans[cur]++;
}
void pfs(int x){
if(x>t) return check();
adj[x]=0; pfs(x+1);
adj[x]=1; pfs(x+1);
}
inline void judge(){
for(int i=1;i<=n;i++) c[i].clear();
for(int i=1;i<=n;i++)
c[h[i]].push_back(i);
for(int i=2;i<=n;i++)
if(c[i].size() && !c[i-1].size()) return ;
t=0; hst=1;
for(int H=2;H<=n;H++)
if(c[H].size()){
for(int i=0;i<c[H-1].size();i++)
for(int j=0;j<c[H].size();j++){
++t; u[t]=c[H][j]; d[t]=c[H-1][i];
}
hst=H;
}
pfs(1);
}
void dfs(int x){
if(x>n) return judge();
for(int i=1;i<=n;i++){
h[x]=i; dfs(x+1);
}
}
class CosmicBlocks{
public:
int getNumOrders(vector <int> blockTypes, int minWays, int maxWays) {
n=blockTypes.size();
memset(ans,0,sizeof(ans));
for(int i=0;i<n;i++) a[i+1]=blockTypes[i];
dfs(1); int ret=0;
for(int i=minWays;i<=maxWays;i++) ret+=ans[i];
return ret;
}
// BEGIN CUT HERE
public:
void run_test(int Case) { if ((Case == -1) || (Case == 0)) test_case_0(); if ((Case == -1) || (Case == 1)) test_case_1(); if ((Case == -1) || (Case == 2)) test_case_2(); if ((Case == -1) || (Case == 3)) test_case_3(); if ((Case == -1) || (Case == 4)) test_case_4(); if ((Case == -1) || (Case == 5)) test_case_5(); if ((Case == -1) || (Case == 6)) test_case_6(); if ((Case == -1) || (Case == 7)) test_case_7(); }
private:
template <typename T> string print_array(const vector<T> &V) { ostringstream os; os << "{ "; for (typename vector<T>::const_iterator iter = V.begin(); iter != V.end(); ++iter) os << '\"' << *iter << "\","; os << " }"; return os.str(); }
void verify_case(int Case, const int &Expected, const int &Received) { cerr << "Test Case #" << Case << "..."; if (Expected == Received) cerr << "PASSED" << endl; else { cerr << "FAILED" << endl; cerr << "\tExpected: \"" << Expected << '\"' << endl; cerr << "\tReceived: \"" << Received << '\"' << endl; } }
void test_case_0() { int Arr0[] = {2,2,2}; vector <int> Arg0(Arr0, Arr0 + (sizeof(Arr0) / sizeof(Arr0[0]))); int Arg1 = 1; int Arg2 = 1; int Arg3 = 6; verify_case(0, Arg3, getNumOrders(Arg0, Arg1, Arg2)); }
void test_case_1() { int Arr0[] = {1,1,1,1,1,1}; vector <int> Arg0(Arr0, Arr0 + (sizeof(Arr0) / sizeof(Arr0[0]))); int Arg1 = 720; int Arg2 = 720; int Arg3 = 1; verify_case(1, Arg3, getNumOrders(Arg0, Arg1, Arg2)); }
void test_case_2() { int Arr0[] = {2,2}; vector <int> Arg0(Arr0, Arr0 + (sizeof(Arr0) / sizeof(Arr0[0]))); int Arg1 = 1; int Arg2 = 2; int Arg3 = 3; verify_case(2, Arg3, getNumOrders(Arg0, Arg1, Arg2)); }
void test_case_3() { int Arr0[] = {1,2}; vector <int> Arg0(Arr0, Arr0 + (sizeof(Arr0) / sizeof(Arr0[0]))); int Arg1 = 1; int Arg2 = 2; int Arg3 = 2; verify_case(3, Arg3, getNumOrders(Arg0, Arg1, Arg2)); }
void test_case_4() { int Arr0[] = {1}; vector <int> Arg0(Arr0, Arr0 + (sizeof(Arr0) / sizeof(Arr0[0]))); int Arg1 = 1; int Arg2 = 1; int Arg3 = 1; verify_case(4, Arg3, getNumOrders(Arg0, Arg1, Arg2)); }
void test_case_5() { int Arr0[] = {1,2,4,8}; vector <int> Arg0(Arr0, Arr0 + (sizeof(Arr0) / sizeof(Arr0[0]))); int Arg1 = 5; int Arg2 = 30; int Arg3 = 27; verify_case(5, Arg3, getNumOrders(Arg0, Arg1, Arg2)); }
void test_case_6() { int Arr0[] = {1,2,3,4,5,6}; vector <int> Arg0(Arr0, Arr0 + (sizeof(Arr0) / sizeof(Arr0[0]))); int Arg1 = 1; int Arg2 = 720; int Arg3 = 4445; verify_case(6, Arg3, getNumOrders(Arg0, Arg1, Arg2)); }
void test_case_7() { int Arr0[] = {7500,1000,7500,1000,7500}; vector <int> Arg0(Arr0, Arr0 + (sizeof(Arr0) / sizeof(Arr0[0]))); int Arg1 = 8; int Arg2 = 88; int Arg3 = 448; verify_case(7, Arg3, getNumOrders(Arg0, Arg1, Arg2)); }
// END CUT HERE
};
// BEGIN CUT HERE
int main()
{
CosmicBlocks ___test;
___test.run_test(-1);
system("pause");
}
// END CUT HERE