Changing Parameter
Make the value of DP a new parameter and make one of the existing parameters the value of DP
Problem: Brand New Problem
Discussion: The official editorial describes the technique very well. Go through the official editorial here
For Implementation see this.
TLE Solution
/* * DATE : 2017-05-30 * Algo : dp */ #include<bits/stdc++.h> using namespace std; /*------- Constants---- */ #define Long long long #define Ulong unsigned long long #define FOR(I,A,B) for(long long I = (A); I < (B) ; ++ I) #define REP(i,n) for( long long i=0 ; i < n ; i++ ) #define mp make_pair #define pb push_back #define all(x) (x).begin(),(x).end() #define PI acos(-1.0) #define EPS 1e-9 #define F first #define S second #define lc ((n)<<1) #define rc ((n)<<1|1) #define db(x) cout << #x << " -> " << x << endl; #define Di(x) int x;scanf("%d",&x) #define in(x) input(x) #define in2(x,y) input(x), input(y) #define in3(x,y,z) input(x), input(y),input(z) #define ins(x) scanf("%s",x) #define ind(x) scanf("%lf",&x) #define ms(ara_name,value) memset(ara_name,value,sizeof(ara_name)) #define IO ios_base::sync_with_stdio(0);cin.tie(0) #define READ freopen("/Users/matrixcode/Desktop/in.txt","r",stdin) #define WRITE freopen("/Users/matrixcode/Desktop/out.txt","w",stdout) template<class T > void input(T &x){ char c = getchar();x = 0; for(;(c<48 || c>57);c = getchar()); for(;c>47 && c<58;c = getchar()) {x = (x<<1) + (x<<3) + c - 48;} } inline long long bigmod(long long p,long long e,long long M){ long long ret = 1; for(; e > 0; e >>= 1){ if(e & 1) ret = (ret * p) % M; p = (p * p) % M; } return ret; } template <class T> inline T gcd(T a,T b){if(b==0)return a;return gcd(b,a%b);} template <class T> inline T modinverse(T a,T M){return bigmod(a,M-2,M);} /***************************** END OF TEMPLATE *******************************/ const int N = 6e5+5; char str[N]; int n,m; int id = 0; map<string,int> Map; int getId(string s) { if(Map.count(s)) return Map[s]; return Map[s] = id++; } vector<int> num; vector<int> v[11]; int dp[2][1<<15]; int pre[1<<15][15]; int calc(int idx) { memset(dp,63,sizeof dp); dp[0][(1<<n)-1]=0; int nv= 0; for(int i=v[idx].size()-1;i>=0;i--){ nv = nv ^1; int now = v[idx][i]; for(int mask=0;mask < 1<<n; mask ++ ){ dp[nv][mask] = dp[nv^1][mask]; if(now < n && (mask & (1<< now)) == 0 ) { int cnt = pre[mask][now]; dp[nv][mask] = min(dp[nv][mask], cnt + dp[nv^1][mask | (1<<now)]); } } //for(int j=0 ;j < 1<<n; j++) printf("dp[%d][%d] = %d\n",i,j,dp[nv][j]); } return dp[nv][0]; } int main() { in(n); for(int i=0;i<1<<n;i++){ int cnt=0; for(int j=n-1;j>=0;j--){ pre[i][j] = cnt; if(i&(1<<j)) cnt++; } } for(int i=0;i<n;i++){ scanf("%s",str); num.push_back(getId(str)); } in(m); for(int i=0;i<m;i++){ int k; in(k); for(int j=0;j<k;j++){ scanf("%s",str); v[i].push_back(getId(str)); } } int sum = 1<<20; int id = -1; for(int i=0;i<m;i++){ int v = calc(i); if(v < sum ) { sum = v; id = i; } } if(id==-1) printf("Brand new problem!\n"); else { cout << id + 1<<endl; int p = n*(n-1)/2 - sum + 1; printf("[:"); REP(i,p) printf("|"); printf(":]\n"); } return 0; }
Accepted Solution
/* * DATE : 2017-05-30 * Algo : dp */ #include<bits/stdc++.h> using namespace std; /*------- Constants---- */ #define Long long long #define Ulong unsigned long long #define FOR(I,A,B) for(long long I = (A); I < (B) ; ++ I) #define REP(i,n) for( long long i=0 ; i < n ; i++ ) #define mp make_pair #define pb push_back #define all(x) (x).begin(),(x).end() #define PI acos(-1.0) #define EPS 1e-9 #define F first #define S second #define lc ((n)<<1) #define rc ((n)<<1|1) #define db(x) cout << #x << " -> " << x << endl; #define Di(x) int x;scanf("%d",&x) #define in(x) input(x) #define in2(x,y) input(x), input(y) #define in3(x,y,z) input(x), input(y),input(z) #define ins(x) scanf("%s",x) #define ind(x) scanf("%lf",&x) #define ms(ara_name,value) memset(ara_name,value,sizeof(ara_name)) #define IO ios_base::sync_with_stdio(0);cin.tie(0) #define READ freopen("/Users/matrixcode/Desktop/in.txt","r",stdin) #define WRITE freopen("/Users/matrixcode/Desktop/out.txt","w",stdout) template<class T > void input(T &x){ char c = getchar();x = 0; for(;(c<48 || c>57);c = getchar()); for(;c>47 && c<58;c = getchar()) {x = (x<<1) + (x<<3) + c - 48;} } inline long long bigmod(long long p,long long e,long long M){ long long ret = 1; for(; e > 0; e >>= 1){ if(e & 1) ret = (ret * p) % M; p = (p * p) % M; } return ret; } template <class T> inline T gcd(T a,T b){if(b==0)return a;return gcd(b,a%b);} template <class T> inline T modinverse(T a,T M){return bigmod(a,M-2,M);} /***************************** END OF TEMPLATE *******************************/ const int N = 6e5+5; char str[N]; int n,m; int id = 0; map<string,int> Map; int getId(string s) { if(Map.count(s)) return Map[s]; return Map[s] = id++; } vector<int> num; vector<int> v[11]; int pre[1<<15][15]; int Next[N][15]; int last[15]; int dp[1<<15][225]; int calc(int id) { for(int i=0;i<n;i++) last[i]=1<<20; for(int i=int(v[id].size())-1;i>=0;i--){ if(v[id][i]<n) last[v[id][i]] = i; for(int j=0;j<n;j++) Next[i][j] = last[j]; } for(int i= 0;i <= n*(n-1)/2; i++ ) dp[0][i] = 1<<20; dp[0][0]=0; for(int i=1;i<1<<n;i++) { for(int j=0;j<=n*(n-1)/2;j++) { dp[i][j] = 1<<20; for(int k = 0;k < n ; k ++ ) { if(i&1<<k){ int added = pre[i][k]; int inv = j-added; if(inv < 0) continue; int pos = dp[i^(1<<k)][inv]; if(pos >= v[id].size()) continue; int t = Next[pos][k]; dp[i][j] = min(dp[i][j], t+1); } } } //for(int j=0;j<=n*(n-1)/2;j++) printf("dp[%d][%d]= %d\n",i,j,dp[i][j]); } for(int i=0;i<=n*(n-1)/2;i++) { if(dp[(1<<n)-1][i] <= v[id].size()) return i; } return 1<<20; } int main() { in(n); for(int i=0;i<1<<n;i++){ int cnt=0; for(int j=n-1;j>=0;j--){ pre[i][j] = cnt; if(i&(1<<j)) cnt++; } } for(int i=0;i<n;i++){ scanf("%s",str); num.push_back(getId(str)); } in(m); for(int i=0;i<m;i++){ int k; in(k); for(int j=0;j<k;j++){ scanf("%s",str); v[i].push_back(getId(str)); } } int sum = 1<<20; int id = -1; for(int i=0;i<m;i++){ int v = calc(i); if(v < sum ) { sum = v; id = i; } } if(id==-1) printf("Brand new problem!\n"); else { cout << id + 1<<endl; int p = n*(n-1)/2 - sum + 1; printf("[:"); REP(i,p) printf("|"); printf(":]\n"); } return 0; }