Problem p01541 (C++) — buggy submission, verdict: Time Limit Exceeded

#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <vector>
using namespace std;
const int MAXN = (int)105;
const int INF = (int)0x3f3f3f3f;
typedef long long LL;

int dist;
int M, N;
int S[MAXN];
int D[MAXN];
LL ans;
LL out_time[MAXN];
map<LL, set<int>> mp;
struct permutation {
  int a[10];
} per;
int percnt;
vector<permutation> P;

bool is_judge() {
  mp.clear();
  for (int i = 2; i <= N; i++)
    if (out_time[i] <= out_time[i - 1])
      return false;
  //    for(int i=1;i<=n;i++) printf("%lld ",out_time[i]);
  //    printf("\\n");
  for (int i = 1; i < N; i++) {
    for (int j = i + 1; j <= N; j++) {
      if (S[i] <= S[j])
        continue;
      if ((out_time[j] - out_time[i]) / (S[i] - S[j]) >= dist)
        continue;
      if ((out_time[j] - out_time[i]) % (S[i] - S[j]) != 0)
        return false;
      int tmpD = (out_time[j] - out_time[i]) / (S[i] - S[j]);
      int ok = 0;
      for (int k = 1; k <= M; k++) {
        if (D[k] == tmpD)
          ok = 1;
      }
      //            printf("ok = %d! , tmpD = %-12d , i = %d , j =
      //            %d\\n",ok,tmpD,i,j);
      if (!ok)
        return false;
      if (mp.count(tmpD)) {
        if (mp[tmpD].count(i))
          return false;
        if (mp[tmpD].count(j))
          return false;
      }
      mp[tmpD].insert(i);
      mp[tmpD].insert(j);
    }
  }
  return true;
}

void update() {
  for (int i = N; i >= 1; i--)
    out_time[i] -= out_time[1];
  //    for(int i=1;i<N;i++)if(out_time[i]>=out_time[i+1]) return;
  //    for(int i=1;i<=N;i++) printf("%lld ",out_time[i]);
  //    printf("\\n");
  if (!is_judge())
    return;
  LL tmpans = 0;
  for (int i = 1; i <= N; i++) {
    LL tmp = out_time[i] + (LL)dist * S[i];
    tmpans = max(tmpans, tmp);
  }
  //    if(tmpans==6577480535){
  //        for(int i=1;i<=N;i++) printf("%lld ",out_time[i]);
  //        printf("\\n");
  //        if(is_judge()) printf("true!\\n");
  //        else printf("false!\\n");
  //        exit(0xff);
  //    }
  //    for(int i=1;i<=n;i++) printf("%lld ",out_time[i]);
  //    printf(" : tmpans = %lld\\n",tmpans);
  ans = min(ans, tmpans);
}

int mark[MAXN];
void DFS1(int cur) {
  if (cur > N) {
    per.a[0] = 1;
    P.push_back(per);
    return;
  }
  for (int i = 1; i <= N; i++)
    if (!mark[i]) {
      per.a[++percnt] = i;
      mark[i] = 1;
      DFS1(cur + 1);
      percnt--;
      mark[i] = 0;
    }
}

void DFS2(int curid, const permutation &now) {
  if (curid > N) {
    update();
    return;
  }
  int cur = now.a[curid];
  if (curid == 1) {
    out_time[cur] = 0;
    DFS2(curid + 1, now);
    return;
  }

  for (int t = 1; t < curid; t++) {
    int pre = now.a[t];
    if (cur < pre) {
      out_time[cur] = out_time[pre] - 1;
      DFS2(curid + 1, now);
      for (int i = 1; i <= M; i++) {
        LL dt = D[i];
        out_time[cur] = out_time[pre] - dt * (S[cur] - S[pre]);
        //            printf("%d-%d :
        //            %lld->%lld\\n",pre,cur,out_time[pre],out_time[cur]);
        DFS2(curid + 1, now);
      }
    }
    if (cur > pre) {
      out_time[cur] = out_time[pre] + 1;
      DFS2(curid + 1, now);
      for (int i = 1; i <= M; i++) {
        LL dt = D[i];
        out_time[cur] = out_time[pre] + dt * (S[pre] - S[cur]);
        //            printf("%d-%d :
        //            %lld->%lld\\n",pre,cur,out_time[pre],out_time[cur]);
        DFS2(curid + 1, now);
      }
    }
  }
}

void solve() {
  for (int perid = 0; perid < P.size(); perid++) {
    DFS2(1, P[perid]);
  }
}

void work() {
  scanf("%d%d", &dist, &N);
  for (int i = 1; i <= N; i++)
    scanf("%d", &S[i]);
  scanf("%d", &M);
  for (int i = 1; i <= M; i++)
    scanf("%d", &D[i]);
  D[++M] = dist;
  ans = (LL)INF * INF;
  DFS1(1);
  //    printf("Pcnt = %d\\n",P.size());
  //    for(int i=0;i<P.size();i++){
  //        for(int k=1;k<=N;k++) printf("%d ",P[i].a[k]);
  //        printf("\\n");
  //    }
  solve();
  printf("%lld\\n", ans);
}

int main() {
#ifdef NNever
// freopen("data.in","r",stdin);
/// freopen("out.txt","w",stdout);
#endif // NNever
  work();
  return 0;
}

/*
input
60516263
5
45
16
94
71
91
4
20586550
54017689
36941264
49153094

output
6577480535
*/


Error: TLE

Fixed submission:

#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <vector>
using namespace std;
const int MAXN = (int)105;
const int INF = (int)0x3f3f3f3f;
typedef long long LL;

int dist;
int n, m;
int S[MAXN];
int D[MAXN];
LL ans;
LL out_time[MAXN];
map<LL, int> mp;
struct permutation {
  int a[10];
} per;
int percnt;
vector<permutation> P;

bool is_judge() {
  mp.clear();
  for (int i = 2; i <= n; i++)
    if (out_time[i] <= out_time[i - 1])
      return false;
  //    for(int i=1;i<=n;i++) printf("%lld ",out_time[i]);
  //    printf("\\n");
  for (int i = 1; i <= n; i++) {
    for (int j = i + 1; j < n; j++) {
      if (S[i] <= S[j])
        continue;
      if ((out_time[j] - out_time[i]) / (S[i] - S[j]) >= dist)
        continue;
      if ((out_time[j] - out_time[i]) % (S[i] - S[j]) != 0)
        return false;
      int tmpD = (out_time[j] - out_time[i]) / (S[i] - S[j]);
      int ok = 0;
      for (int k = 1; k <= m; k++) {
        if (D[k] == tmpD)
          ok = 1;
      }
      if (!ok)
        return false;
      if (mp.count(tmpD))
        return false;
      mp[tmpD]++;
    }
  }
  return true;
}

void update() {
  if (!is_judge())
    return;
  LL tmpans = 0;
  for (int i = 1; i <= n; i++)
    tmpans = max(tmpans, out_time[i] + (LL)dist * S[i]);
  //    for(int i=1;i<=n;i++) printf("%lld ",out_time[i]);
  //    printf(" : tmpans = %lld\\n",tmpans);
  ans = min(ans, tmpans);
}

int mark[MAXN];
void DFS1(int cur) {
  if (cur > n) {
    per.a[0] = 1;
    P.push_back(per);
    return;
  }
  for (int i = 2; i <= n; i++)
    if (!mark[i]) {
      per.a[++percnt] = i;
      mark[i] = 1;
      DFS1(cur + 1);
      percnt--;
      mark[i] = 0;
    }
}

void DFS2(int curid, permutation now) {
  if (curid >= n) {
    update();
    return;
  }
  int cur = now.a[curid];
  for (int t = 0; t < curid; t++) {
    int pre = now.a[t];
    if (cur < pre) {
      out_time[cur] = out_time[pre] - 1;
      DFS2(curid + 1, now);
      for (int i = 1; i <= m; i++) {
        LL dt = D[i];
        out_time[cur] = out_time[pre] - dt * (S[cur] - S[pre]);
        DFS2(curid + 1, now);
      }
      LL dt = dist;
      while (S[cur] > S[pre] && out_time[pre] - dt * (S[cur] - S[pre]) > 0) {
        out_time[cur] = out_time[pre] - dt * (S[cur] - S[pre]);
        DFS2(curid + 1, now);
      }
    }
    if (cur > pre) {
      out_time[cur] = out_time[pre] + 1;
      DFS2(curid + 1, now);
      for (int i = 1; i <= m; i++) {
        LL dt = D[i];
        out_time[cur] = out_time[pre] + dt * (S[pre] - S[cur]);
        DFS2(curid + 1, now);
      }
      LL dt = dist;
      while (dt <= dist + 100) {
        out_time[cur] = out_time[pre] + dt * (S[pre] - S[cur]);
        DFS2(curid + 1, now);
      }
    }
  }
}

void solve() {
  out_time[1] = 0LL;
  for (int perid = 0; perid < P.size(); perid++) {
    permutation now = P[perid];
    DFS2(1, now);
  }
}

void work() {
  scanf("%d%d", &dist, &n);
  for (int i = 1; i <= n; i++)
    scanf("%d", &S[i]);
  scanf("%d", &m);
  for (int i = 1; i <= m; i++)
    scanf("%d", &D[i]);
  ans = (LL)INF * INF;
  out_time[1] = 0;
  DFS1(2);
  //    printf("Pcnt = %d\\n",P.size());
  //    for(int i=0;i<P.size();i++){
  //        for(int k=1;k<=n-1;k++) printf("%d ",P[i].a[k]);
  //        printf("\\n");
  //    }
  solve();
  printf("%lld\\n", ans);
}

int main() {
#ifdef NNever
// freopen("data.in","r",stdin);
/// freopen("out.txt","w",stdout);
#endif // NNever
  work();
  return 0;
}