题目链接: http://codeforces.com/gym/100917/problem/M
----------------------------------------------------------------------------
每次写$dp$都因为思路还不成熟就上了导致经常写出状态冗余的代码
这题看数据范围显然是状压$dp$
然后注意优雅地使用位运算来减少代码长度就好了
1 #include <cstdio> 2 #include <cstring> 3 #include <cmath> 4 #include <algorithm> 5 using namespace std; 6 int ans[12], way[1 << 10]; 7 long long f[11][1 << 10][1 << 10]; 8 int n, a, b, q, cnt; 9 long long dfs(int r, int sta, int mask) 10 { 11 long long &re = f[r][sta][mask]; 12 if(re != -1) 13 return re; 14 if(r == n) 15 return re = (mask == (1 << n) - 1); 16 re = 0; 17 for(int i = 1; i <= cnt; ++i) 18 if(!((~sta) & way[i] & mask)) 19 re += dfs(r + 1, way[i], way[i] | mask); 20 return re; 21 } 22 bool dfs2(long long x, int r, int sta, int mask) 23 { 24 if(r == n) 25 return 1; 26 for(int i = 1; i <= cnt; ++i) 27 if(!((~sta) & way[i] & mask)) 28 { 29 if(x > f[r + 1][way[i]][way[i] | mask]) 30 x -= f[r + 1][way[i]][way[i] | mask]; 31 else 32 { 33 ans[r + 1] = way[i]; 34 return dfs2(x, r + 1, way[i], way[i] | mask); 35 } 36 } 37 return 0; 38 } 39 int calc1(int x) 40 { 41 int re = 0; 42 for(; x; x -= x & -x, ++re); 43 return re; 44 } 45 void output(int x) 46 { 47 for(int i = n - 1; i >= 0; --i) 48 printf("%d", (x & (1 << i)) != 0); 49 puts(""); 50 } 51 int main() 52 { 53 memset(f, -1, sizeof f); 54 scanf("%d%d%d%d", &n, &a, &b, &q); 55 for(int i = 1; i < (1 << n); ++i) 56 { 57 int tmp = calc1(i); 58 if(tmp >= a && tmp <= b) 59 way[++cnt] = i; 60 } 61 long long x; 62 dfs(0, 0, 0); 63 while(q--) 64 { 65 scanf("%lld", &x); 66 if(dfs2(x, 0, 0, 0)) 67 { 68 for(int i = 1; i <= n; ++i) 69 output(ans[i]); 70 } 71 else 72 puts("No such matrix."); 73 puts(""); 74 } 75 return 0; 76 }
时间: 2024-10-08 17:53:53