USACO 6.2 chapters you know nothing about QAQ search and pruning

Fence Rails

Subject to the effect

N<=50The number ofA1,A2...

1023Number, each number 数值<=128, B

Q. A number of them can be split into B, seeking the largest number of

Sample interpretation

A:
30=30
40=18+19+3
50=15+16+17+2
25=24
B:
15 (ok)
16 (ok)
17 (ok)
18 (ok)
19 (ok)
20
21
25
24 (ok)
30 (ok)

So up to 7

answer

First, if the sort of B, assuming the optimal number of k

Obviously if k viable, then the first k B after ordering possible

If k and k-1 then the viable viable, but also to meet the half heald

Sort first half + B + in descending discharge (4 times out point)

#include <bits/stdc++.h>
#define rep(i,a,n) for (int i=a;i<n;i++)
#define per(i,a,n) for (int i=n-1;i>=a;i--)

using namespace std;

const string filename = "fence8";

void usefile(){
  freopen((filename+".in").c_str(),"r",stdin);
  freopen((filename+".out").c_str(),"w",stdout);
}

int n;
int a[100];
int la[100];
int suma;
int R;
int r[1100];
int sumr[1100];

int dfs(int idx){
  per(i,0,n){
    if(a[i] < r[idx]){
      return false;
    }
    if(a[i] ==  a[i+1] && la[i] == la[i+1]){
      continue;
    }
    if(la[i] < r[idx]){
      continue;
    }
    if(idx == 0){
      return true;
    }
    la[i] -= r[idx];
    int ret = dfs(idx-1);
    la[i] += r[idx];
    if(ret){
      return true;
    }
  }
  return false;
}

bool test(int idx){
  if(sumr[idx] > suma)return false;
  return dfs(idx);
}

int main(){
  usefile();
  scanf("%d",&n);
  rep(i,0,n){
    scanf("%d",a+i);
  }
  rep(i,0,n){
    la[i]=a[i];
    suma += a[i];
  }
  sort(a,a+n);

  scanf("%d",&R);
  rep(i,0,R){
    scanf("%d",r+i);
  }
  sort(r,r+R);
  if(r[0] > a[n-1]){
    cout<<0<<endl;
    return 0;
  }
  sumr[0]=r[0];
  rep(i,1,R){
    sumr[i]=sumr[i-1]+r[i];
  }
  int l=0,r=R;
  while(l+1<r){
    int mid = (l+r)/2;
    if(test(mid)){
      l = mid;
    }else{
      r = mid;
    }
  }
  cout<<l+1<<endl;
  return 0;
}

B is added to the enumeration process optimization tle enumerated the same length 5

int dfs(int idx,int stn = n){
  per(i,0,stn){
    if(a[i] < r[idx]){
      return false;
    }
    if(a[i] ==  a[i+1] && la[i] == la[i+1]){
      continue;
    }
    if(la[i] < r[idx]){
      continue;
    }
    if(idx == 0){
      return true;
    }
    la[i] -= r[idx];
    int ret;
    if(r[idx] == r[idx+1]){
      ret = dfs(idx-1,i+1);
    }else{
      ret = dfs(idx-1);
    }
    la[i] += r[idx];
    if(ret){
      return true;
    }
  }
  return false;
}

An increase of residual wood AC invalid

#include <bits/stdc++.h>
#define rep(i,a,n) for (int i=a;i<n;i++)
#define per(i,a,n) for (int i=n-1;i>=a;i--)

using namespace std;

const string filename = "fence8";

void usefile(){
  freopen((filename+".in").c_str(),"r",stdin);
  freopen((filename+".out").c_str(),"w",stdout);
}

int n;
int a[100];
int la[100];
int suma;
int R;
int r[1100];
int sumr[1100];

int dfs(int idx,int stn = n){
  if(suma < sumr[idx]){
    return false;
  }
  per(i,0,stn){
    if(a[i] < r[idx]){
      return false;
    }
    if(a[i] ==  a[i+1] && la[i] == la[i+1]){
      continue;
    }
    if(la[i] < r[idx]){
      continue;
    }
    if(idx == 0){
      return true;
    }
    la[i] -= r[idx];
    suma-=r[idx];
    bool predel = la[i] < r[0];
    if(predel){
      suma -= la[i];
    }
    int ret;
    if(idx > 0 && r[idx-1] == r[idx]){
      ret = dfs(idx-1,i+1);
    }else{
      ret = dfs(idx-1);
    }
    if(predel){
      suma += la[i];
    }
    suma+=r[idx];
    la[i] += r[idx];
    if(ret){
      return true;
    }
  }
  return false;
}

bool test(int idx){
  if(sumr[idx] > suma)return false;
  return dfs(idx);
}

int main(){
  usefile();
  scanf("%d",&n);
  rep(i,0,n){
    scanf("%d",a+i);
  }
  rep(i,0,n){
    la[i]=a[i];
    suma += a[i];
  }
  sort(a,a+n);

  scanf("%d",&R);
  rep(i,0,R){
    scanf("%d",r+i);
  }
  sort(r,r+R);
  if(r[0] > a[n-1]){
    cout<<0<<endl;
    return 0;
  }
  sumr[0]=r[0];
  rep(i,1,R){
    sumr[i]=sumr[i-1]+r[i];
  }
  int l=0,r=R;
  while(l+1<r){
    int mid = (l+r)/2;
    if(test(mid)){
      l = mid;
    }else{
      r = mid;
    }
  }
  cout<<l+1<<endl;
  return 0;
}

In summary binary search storm + + + Save branch processing sequence greedy

Cryptcowgraphy

Subject to the effect

A string can be passed so that the operation becomes several positive

Begin the Escape execution at the Break of Dawn

Time: Choose ...C...O...W..., the C->Ocharacter string and the O->Wstring of exchange, and then remove the three selected C, O,W

answer

Obviously special sentenced play table

We already know that the initial target string and string

So if feasible, then the number of relationship there C=O=W =(len(起始串)-len(目标串))/3, so pre-screened optimization is a statistical number of each character, and the target string to compare

Therefore, when comparison is 可能, the answer to either 00, or a number of letter C

We can optimize the point

  1. The number of letters Statistics
  2. COW divided at any time is a sub-target string string
  3. O first search order
  4. String hash [Note that this method if you are playing cf, then it is likely to be hack

Note that the input is a line .... so do notscanf %s

#include <bits/stdc++.h>
#define rep(i,a,n) for (int i=a;i<n;i++)
#define per(i,a,n) for (int i=n-1;i>=a;i--)

using namespace std;

const string filename = "cryptcow";

void usefile(){
  freopen((filename+".in").c_str(),"r",stdin);
  freopen((filename+".out").c_str(),"w",stdout);
}
const char Goal[] = "Begin the Escape execution at the Break of Dawn";
const int Mod = 999983;

char s[110];
int ans, cnt;
bool hsh[Mod];

// 删除a b c位置上的, 交换a->b b->c
void work(int a, int b, int c) {
  static char tmp[100];
  int len = strlen(s), tot = 0;
  for(int i = 0; i < a; ++i) {
    tmp[tot++] = s[i];
  }
  for(int i = b + 1; i < c; ++i) {
    tmp[tot++] = s[i];
  }
  for(int i = a + 1; i < b; ++i) {
    tmp[tot++] = s[i];
  }
  for(int i = c + 1; i < len; ++i) {
    tmp[tot++] = s[i];
  }
  tmp[tot] = 0;
  strcpy(s, tmp);
}

int getHash() {
  int ret = 0, len = strlen(s);
  for(int i = 0; i < len; ++i) {
    int num = (s[i]==' ')?1:(isupper(s[i]) ? s[i] - 'A' + 2 : s[i] - 'a' + 28);
    ret = (ret * 57 + num) % Mod;
  }
  return ret;
}

bool dfs(int depth) {
  if(strcmp(s, Goal) == 0) {
    ans = depth;
    return true;
  }
  int x = getHash();
  if(hsh[x]) {
    return false;
  }
  hsh[x] = true;
  ++cnt;
  // 被C O W 分割的 字串应该是Goal的连续子串
  static char sub[100];
  int len = strlen(s);
  int c[20], o[20], w[20];
  c[0] = o[0] = w[0] = 0;
  for(int i = 0, j = 0; i < len; ++i) {
    if(s[i] == 'C' || s[i] == 'O' || s[i] == 'W') {
      if(s[i] == 'C') {
        c[++c[0]] = i;
      }
      if(s[i] == 'O') {
        o[++o[0]] = i;
      }
      if(s[i] == 'W') {
        w[++w[0]] = i;
      }
      sub[j] = 0;
      if(!strstr(Goal, sub)) { //
        return false;
      }
      j = 0;
    }
    else {
      sub[j++] = s[i];
    }
  }
  // C = W = O
  if(o[0] != c[0] || o[0] != w[0] || w[0] != c[0]) {
    return false;
  }
  char pre[100];
  strcpy(pre, s); // 递归暂存
  // 查找顺序 先找O
  rep(j,1,o[0]+1){
    per(k,1,w[0]+1){
      if(w[k] < o[j])break;
      rep(i,1,c[0]+1){
      if(c[i] > o[j])break;
        work(c[i], o[j], w[k]);
        bool ret = dfs(depth + 1);
        if(ret){
          return true;
        }
        if(cnt > 200000) { // ............................
          return false;
        }
        strcpy(s, pre);
      }
    }
  }
  return false;
}


int main() {
  usefile();
  cin.getline(s,100);
  // scanf("%s",s);
  int ret = dfs(0);
  printf("%d %d\n", ret, ans);
  return 0;
}

Cowcycles

Subject to the effect

25 <= F1 < F2 <= 80

In [F1,F2]looking for the range of [1,5]the number off1,f2..

5 <= R1 < R2 <= 40

In [R1,R2]looking for the range of [1,10]the number ofr1,r2..

ratio(i,j) = fi/rj

In max ratio/min ratio >= 3the lower limit

All the ratio(i,j)sorting, the sorted array is minimized相邻值 的差 的方差

Seeking specific programs

answer

ratio(i1,j1)/ratio(i2,j2) = i1*j2/i2*j1

To this value is greater than the maximum value of 3, notes are positive, i.e.(max(i)*max(j))/(min(i)*min(j)) >= 3

Since then ratio must first sort, and then minimize the variance difference, I felt there was no way to push, violence can only search

optimization

  1. The default limit cut branches
  2. A small number, the calculation process is relatively orderly -> + insertion sort order is calculated
  3. Search found junior variance modification formula, save the outermost layer 1/nhas only Comparativesum{平方}+(sum{}平方)/n

Note that the following code after USACO but there is a potential risk, 浮点数比大小!!if it is to play cf, may be fork

#include <bits/stdc++.h>
#define rep(i,a,n) for (int i=a;i<n;i++)
#define per(i,a,n) for (int i=n-1;i>=a;i--)

using namespace std;

const string filename = "cowcycle";

void usefile(){
  freopen((filename+".in").c_str(),"r",stdin);
  freopen((filename+".out").c_str(),"w",stdout);
}

int s1[20],s2[20];
int ans1[20],ans2[20];
int F,F1,F2;
int R,R1,R2;
int cnt;
double rate[100],diff[100];
double minvf=10000000;

void count(){
  int k=0;
  double sum=0,avg,vf=0,sumf=0,p;
  // 数据量小 采用插入排序
  rep(i,0,F){
    rep(j,0,R){
      p=(double)s1[i]/s2[j];
      int l=++k;
      while (rate[l-1]>=p) {
        rate[l]=rate[l-1];
        l--;
      }
      rate[l]=p;
    }
  }
  rep(i,1,cnt){
    diff[i]=rate[i+1]-rate[i];
    sum+=diff[i];
    sumf+=diff[i]*diff[i];
  }
  avg=sum/(cnt-1);// 相邻值的差的个数 比值的个数少1
  vf=sumf-sum*avg;
  if (vf<minvf)  {
    minvf=vf;
    memcpy(ans1,s1,sizeof(int)*F);
    memcpy(ans2,s2,sizeof(int)*R);
  }
}

// 枚举后齿轮 从w 到R2-R+k+1
void sc2(int k,int w){
  if (k==R){
    if (s1[F-1]*s2[R-1]<3*s1[0]*s2[0]) // 题目限制条件剪枝
      return;
    count();
    return;
  }
  rep(i,w,R2-R+k+2){
    s2[k]=i;
    sc2(k+1,i+1);
  }
}

// 枚举前齿轮 从w到F2-F+k+1
void sc1(int k,int w){
  if (k==F)  {
    sc2(0,R1);
    return;
  }
  rep(i,w,F2-F+k+2){
    s1[k]=i;
    sc1(k+1,i+1);
  }
}

int main() {
  usefile();
  cin>> F >> R >> F1 >> F2 >> R1 >> R2;
  cnt=F*R;
  sc1(0,F1);
  rep(i,0,F){
    cout << ans1[i] << " \n"[i==F-1];
  }
  rep(i,0,R){
    cout << ans2[i] << " \n"[i==R-1];
  }
  return 0;
}

to sum up

Search + pruning shears exactly how to cut

Quoted the words of a Gangsterhttps://apps.topcoder.com/forums/?module=Thread&threadID=669047&start=0&mc=6#1216077

Well, if the optimizations change the complexity of the solution asymptotically, you can quite sure.

Otherwise you can't depend on anything, I think.

It is important to find a clear change pruning algorithm complexity.

Conversely Analysis Question 1

The remaining volume processing, should be able to optimize the number of leaf nodes of the search tree, it is crucial

Repeat volume search process to optimize the number of enumeration volume, there are a plurality of the same volume, from 可放空间数the 相同个数power, optimized to? ? ? Do not know how to express, but a significant reduction in repeat enumeration is yes

Descending try to optimize the number of the end? ()

Guess you like

Origin www.cnblogs.com/CroMarmot/p/11112572.html