noip2016 (difficult as HLJOI2016???)

D1:

T2:

感觉挺难的但是部分分的提示挺充足

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<iostream>
 4 #include<cstring>
 5 #include<cstdlib>
 6 #include<cmath>
 7 using namespace std;
 8 template<typename T>
 9 inline void read(T &a){
10     a=0;T b=1;char x=getchar();
11     while(x<'0'||'9'<x){
12         if(x=='-')b=-1;
13         x=getchar();
14     }
15     while('0'<=x&&x<='9'){
16         a=(a<<1)+(a<<3)+x-'0';
17         x=getchar();
18     }
19     a*=b;
20 }
21 char C_[50];
22 int TEMP;
23 template<typename T>
24 inline void write(T a){
25     if(a<0){
26          putchar('-');
27          a=-a;
28     }
29     do{
30          C_[++TEMP]=a%10+'0';
31          a/=10;
32     }while(a);
33     while(TEMP)putchar(C_[TEMP--]);
34 }
35 /*
36 从 u到v 的等差单调路径 有贡献
37 当且仅当路径经过点 i 且路径起点与 i 的距离等于 wi
38 
39 于是差分
40 把u->v <=> u->lca lca->v <=> 
41 u->root(贡献+1) 
42 lca->root(贡献-1) 
43 
44 root->fa[lca](贡献-1) 
45 root->(贡献+1) 
46 */
47 int main()
48 {
49      return 0;
50 }
running

。。。(注意提示)

感觉自己想麻烦了,其实就是找一个好维护的不变量,预处理出来,再O(logn) 以内的复杂度查询

 总结

1.不要痴迷于想正解,先打暴力在想正解,否则就会有时间想没时间写

2.能设计O(n)算法就不要使用数据结构,能省一个logn 的复杂度

3.这种统计类问题往往不能直接一个一个加,而是构造出几个不变量和一个关系式,以此查询及统计贡献

and 条件和贡献之间往往不是等价的、删除的复杂度很高,所以要使用差量法进行统计

4.新思路:全局桶+增量法(由于删除操作很费时间所以我们记录初始时 的总贡献 和结束时的总贡献,将其作差就是这一过程中的贡献)

5.正解往往是各种部分分算法的综合,所以先想部分分在想正解有帮助

安利一个实用知识点--->Tarjan O(n+q)求lca

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<iostream>
 4 #include<cstring>
 5 #include<cstdlib>
 6 #include<cmath>
 7 using namespace std;
 8 template<typename T>
 9 inline void read(T &a){
10     a=0;T b=1;char x=getchar();
11     while(x<'0'||'9'<x){
12         if(x=='-')b=-1;
13         x=getchar();
14     }
15     while('0'<=x&&x<='9'){
16         a=(a<<1)+(a<<3)+x-'0';
17         x=getchar();
18     }
19     a*=b;
20 }
21 char C_[50];
22 int TEMP;
23 template<typename T>
24 inline void write(T a){
25     if(a<0){
26          putchar('-');
27          a=-a;
28     }
29     do{
30          C_[++TEMP]=a%10+'0';
31          a/=10;
32     }while(a);
33     while(TEMP)putchar(C_[TEMP--]);
34 }
35 const int maxn=5e5+5;
36 int fst[maxn][2],nxt[maxn<<1][2],to[maxn<<1][2],edge_count[2]={1,1},lca[maxn<<1];
37 inline void add(int x,int y,bool b){
38     edge_count[b]++;
39     to[edge_count[b]][b]=y;
40     nxt[edge_count[b]][b]=fst[x][b];
41     fst[x][b]=edge_count[b];
42 }
43 int f[maxn];
44 int find(int x){return f[x]==x ? x : f[x]=find(f[x]) ;}
45 bool vis[maxn];
46 //标记是否找过,找过则对方结点的最上层为lca ,利用了dfs序性质 
47 
48 int n,m,s;
49 void dfs(int u){
50     f[u]=u;//dsu_init
51     vis[u]=1;
52     for(int i=fst[u][0];i;i=nxt[i][0]){
53         int v=to[i][0];
54         if(!vis[v]){
55             dfs(v);
56             f[v]=u;
57         }
58     }
59     for(int i=fst[u][1];i;i=nxt[i][1]){
60         int v=to[i][1];
61         if(vis[v]){
62             lca[i]=lca[i^1]=find(v);
63         }
64     }
65 }
66 int main()
67 {
68     read(n);read(m);read(s);
69     for(int i=1,x,y;i<n;i++){
70         read(x);read(y);
71         add(x,y,0);add(y,x,0);
72     }
73     for(int i=1,x,y;i<=m;i++){
74         read(x);read(y);
75         add(x,y,1);add(y,x,1);
76     }
77     dfs(s);
78     for(int i=1;i<=m;i++)write(lca[i<<1]),putchar('\n');
79      return 0;
80 }
Tarjan+dsu 求lca

 

D1:

T1:

注意各种定理的使用条件

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<cstring>
 4 using namespace std;
 5 int t,k;
 6 const int maxn=2e3+5;
 7 /*
 8 由于无法使用 inv的递推公式,并且不能使用CRT
 9 考虑杨辉三角递推(n*m)
10 
11 */
12 int n,m;
13 int c[maxn][maxn],ans[maxn][maxn];
14 int main(){
15     freopen("problem.in","r",stdin);
16     freopen("problem.out","w",stdout);
17     scanf("%d%d",&t,&k);
18     
19     for(int i=0;i<=maxn-5;i++)c[i][0]=1;
20     
21     for(int i=1;i<=maxn-5;i++)for(int j=1;j<=i;j++){
22         c[i][j]=(c[i-1][j]+c[i-1][j-1])%k;
23         if(!c[i][j])ans[i][j]++;
24     }
25     /*for(int i=0;i<=20;i++){
26     for(int j=0;j<=i;j++)printf("%d ",c[i][j]);
27     printf("\n");
28     }*/
29     
30     
31     for(int i=1;i<=maxn-5;i++)for(int j=1;j<=maxn-5;j++)
32     ans[i][j]+=(ans[i-1][j]+ans[i][j-1]-ans[i-1][j-1]);
33     
34     /*for(int i=0;i<=20;i++){
35     for(int j=0;j<=i;j++)printf("%d ",ans[i][j]);
36     printf("\n");
37     }*/
38     for(int i=1;i<=t;i++){
39         scanf("%d%d",&n,&m);
40         printf("%d\n",ans[n][m]);
41     }
42     return 0;
43 }
problem

 

T2:

force!!!注意O(nlogn)极限是3e6

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 #include<cmath>
 5 #include<cstdlib>
 6 #include<algorithm>
 7 #include<queue>
 8 #define LL long long
 9 using namespace std;
10 const int maxn=1e5+5;
11 const int maxm=7e6+5;
12 const int INF=1e9;
13 int n,m,q,t,cnt;
14 LL u,v;
15 int num[maxn];
16 inline int getpart(int x){
17     LL ans=u*x/v;
18     return (int )ans;
19 }
20 int que[maxm][3];
21 int f[3]={1,1,1},r[3];
22 int main(){
23     freopen("earthworm.in","r",stdin);
24     freopen("earthworm.out","w",stdout);
25     
26     scanf("%d%d%d%lld%lld%d",&n,&m,&q,&u,&v,&t);
27     for(int i=1;i<=n;i++){
28         scanf("%d",&num[i]);
29     }
30     sort(num+1,num+n+1);
31     for(int i=n;i>=0;i--){
32         que[++r[0]][0]=num[i];
33     }
34     //for(int i=1;i<=n;i++)printf("%d ",que[i][0]);
35     //printf("\n");
36 
37     for(int i=1;i<=m;i++){
38         int k=-1,Max=-INF;
39         if(f[0]<=r[0]  && que[f[1]][1]>=Max){
40             Max=que[f[0]][0];
41             k=0;
42         }
43          if(f[1]<=r[1] && que[f[1]][1]>=Max){
44             Max=que[f[1]][1];
45             k=1;
46         }
47          if(f[2]<=r[2] &&que[f[2]][2]>=Max){
48             Max=que[f[2]][2];
49             k=2;
50         }
51         LL ans=Max+cnt;
52         cnt+=q;
53         que[++r[1]][1]=getpart(ans)-cnt;
54         que[++r[2]][2]=ans-getpart(ans)-cnt;
55         f[k]++;
56 
57         if(i%t==0)printf("%d ",ans);
58 
59     }
60     printf("\n");
61 
62    /* for(int i=0;i<3;i++){
63     for(int j=f[i];j<=r[i];j++)printf("%d",que[j][i]+cnt);
64     putchar('\n');}*/
65 //printf("%d\n",r[0]+r[1]+r[2]-f[0]-f[1]-f[2]+3);
66 
67     for(int i=1;i<=n+m;i++){
68         int k=-1,Max=-INF;
69         if(f[0]<=r[0]  && que[f[0]][0]>=Max){
70             Max=que[f[0]][0];
71             k=0;
72         }
73          if(f[1]<=r[1] && que[f[1]][1]>=Max){
74             Max=que[f[1]][1];
75             k=1;
76         }
77          if(f[2]<=r[2] &&que[f[2]][2]>=Max){
78             Max=que[f[2]][2];
79             k=2;
80         }
81      //  printf("%d %d\n",k,Max+cnt);
82         if(i%t==0)printf("%d ",Max+cnt);
83         f[k]++;
84     }
85     return 0;
86 }
force

O(nlogn):

利用好单调性,然后分析分析神奇性质就可以O(n) 进行选择了,

!!!注意开LongLong!!!

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 #include<cmath>
 5 #include<cstdlib>
 6 #include<algorithm>
 7 #include<queue>
 8 #define LL long long
 9 using namespace std;
10 const int maxn=1e5+5;
11 const int maxm=7e6+5;
12 const LL  INF=1ll<<62;
13 int n,m,t;
14 LL u,v,cnt=0ll,q;
15 LL num[maxn];
16 inline LL getpart(LL x){
17     return u*x/v;
18 }
19 LL que[maxm][4];
20 int f[4]={1,1,1,0},r[4]={0,0,0,0};
21 int main(){
22     scanf("%d%d%lld%lld%lld%d",&n,&m,&q,&u,&v,&t);
23     for(int i=1;i<=n;i++){
24         scanf("%lld",&num[i]);
25     }
26     sort(num+1,num+n+1);
27   /*  for(int i=1;i<=n;i++)printf("%d ",num[i]);
28     printf("\n");*/
29     for(int i=n;i;i--){
30         que[++r[0]][0]=num[i];
31     }
32    /*for(int i=1;i<=n;i++)printf("%d ",que[i][0]);
33     printf("\n");*/
34 
35     for(int i=1;i<=m;i++){
36         int k=-1;
37         LL Max=-INF;
38         if(f[0]<=r[0]  && que[f[0]][0]>=Max){
39             Max=que[f[0]][0];
40             k=0;
41         }
42          if(f[1]<=r[1] && que[f[1]][1]>=Max){
43             Max=que[f[1]][1];
44             k=1;
45         }
46          if(f[2]<=r[2] &&que[f[2]][2]>=Max){
47             Max=que[f[2]][2];
48             k=2;
49         }
50         LL ans=cnt+Max;//cout<<ans<<endl;
51         cnt+=q;
52         que[++r[1]][1]=getpart(ans)-cnt;
53         que[++r[2]][2]=ans-getpart(ans)-cnt;
54         f[k]++;
55 
56         if(i%t==0)printf("%lld ",ans);
57 
58     }
59     printf("\n");
60 
61    /* for(int i=0;i<3;i++){
62     for(int j=f[i];j<=r[i];j++)printf("%d",que[j][i]+cnt);
63     putchar('\n');}*/
64 //printf("%d\n",r[0]+r[1]+r[2]-f[0]-f[1]-f[2]+3);
65 
66     for(int i=1;i<=n+m;i++){
67         int k=-1;
68         LL Max=-INF;
69         if(f[0]<=r[0]  && que[f[0]][0]>=Max){
70             Max=que[f[0]][0];
71             k=0;
72         }
73          if(f[1]<=r[1] && que[f[1]][1]>=Max){
74             Max=que[f[1]][1];
75             k=1;
76         }
77          if(f[2]<=r[2] &&que[f[2]][2]>=Max){
78             Max=que[f[2]][2];
79             k=2;
80         }
81         f[k]++;
82      //  printf("%d %d\n",k,Max+cnt);
83         if(i%t==0)printf("%lld ",cnt+Max);
84     }
85     return 0;
86 }
earthworm

T3:

 本题想到了正解但是考场上没有调试对(不要在最后的时候还在写代码,暴力优先[感谢Duan2baka 大佬的真心劝告],555)

wa:

带入公式错了

没有被某一条抛物线覆盖的时候记得在加一只鸟

去重

最后浮点数的精度问题,最高是3次项所以判断是否为0应该比较是否< 1e-6

  1 #include<cstdio>
  2 #include<cmath>
  3 #include<cstring>
  4 #include<map>
  5 #include<ctime>
  6 #include<cstdlib>
  7 #define LL long long
  8 #define DB double
  9 using namespace std;
 10 /*
 11 状压Dp
 12 
 13 */
 14 int p;
 15 struct bird{
 16     DB a,b;int cnt;
 17     bird(DB A=0.0,DB B=0.0,int C=0):a(A),b(B),cnt(C){}
 18     const bool operator ==(const bird & xx)const{
 19         return abs(b/xx.b-a/xx.a)<0.01;
 20     }
 21 }b[500];
 22 int finish[(1<<18)+5];
 23 struct Node{
 24     DB x,y;
 25     
 26     inline bool okbird(const bird &k){
 27         return abs(k.a*x*x+k.b*x-y)<0.01;
 28     }
 29     
 30 }a[20];
 31 inline bool judge(Node a1,Node a2){
 32     DB x=a1.x-a2.x;
 33     DB y=a1.y/a1.x-a2.y/a2.x;
 34     if(abs(y)<0.01 || abs(x)<0.01 || x*y>0)return 0;//无解 或者 无数解 或者 a>0
 35     return 1;
 36 }
 37 inline bird get_ans(Node a1,Node a2){
 38     DB x=a1.x-a2.x;
 39     DB y=a1.y/a1.x-a2.y/a2.x;
 40     DB ansa=y/x;
 41     DB ansb=a1.y/a1.x-ansa*a1.x;
 42     return bird(ansa,ansb);
 43 }
 44 inline int read(){
 45     int a=0;char x=getchar();
 46     while(x<'0'||'9'<x)x=getchar();
 47     while('0'<=x && x<='9'){
 48         a=(a<<1)+(a<<3)+x-'0';
 49         x=getchar();
 50     }
 51     return a;
 52 }
 53 int t,n,m;
 54 int f[(1<<18)+5];
 55 bool gunk[20];
 56 
 57 int main(){
 58     //freopen("angrybirds.in","r",stdin);
 59     //freopen("angrybirds.out","w",stdout);
 60     t=read();
 61     for(int T=1;T<=t;T++){
 62         n=read();m=read();
 63         
 64         memset(gunk,0,sizeof(gunk));
 65         //memset(finish,0,sizeof(finish));
 66         for(int i=1;i<=n;i++)scanf("%lf%lf",&a[i].x,&a[i].y);
 67         //if(n==2){printf(judge(a[1],a[2]) ? "1\n" : "2\n" );continue;}
 68         
 69         p=0;
 70         for(int i=1;i<n;i++)
 71             for(int j=i+1;j<=n;j++)
 72             //printf("i%d j%d:",i,j);
 73             //printf("%d\n",judge(a[i],a[j]));
 74             
 75                 if(judge(a[i],a[j])){
 76                 b[p]=get_ans(a[i],a[j]);
 77                 
 78                 for(int k=1;k<=n;k++){
 79                     //printf("%d %d ",k,a[k].okbird(b[p]));
 80                     if(a[k].okbird(b[p]))b[p].cnt|=(1<<(k-1)),gunk[k]=1;
 81                 }
 82             //printf("%d",b[p].cnt);
 83             
 84             if(finish[b[p].cnt]!=T){
 85                     finish[b[p].cnt]=T;
 86                     p++;
 87                 }
 88             }
 89         
 90         for(int i=1;i<=n;i++)if(!gunk[i])b[p++].cnt=1<<(i-1);
 91         
 92         memset(f,0x3f,sizeof(f));
 93         f[0]=0;
 94         for(int s=0;s<(1<<n);s++){
 95             for(int k=0;k<p;k++)f[s|b[k].cnt]=min(f[s|b[k].cnt],f[s]+1);
 96         }
 97         printf("%d\n",f[(1<<n)-1]);
 98     }
 99     return 0;
100 }
101 /*
102 1
103 2 0
104 1.00 3.00
105 3.00 3.00
106 */
angrybirds

 ac:

  1 #include<cstdio>
  2 #include<cmath>
  3 #include<cstring>
  4 #include<map>
  5 #include<ctime>
  6 #include<cstdlib>
  7 #define LL long long
  8 #define DB double
  9 using namespace std;
 10 /*
 11 状压Dp
 12 
 13 */
 14 const double lit=1e-6;
 15  
 16 int p;
 17 struct bird{
 18     DB a,b;int cnt;
 19     bird(DB A=0.0,DB B=0.0,int C=0):a(A),b(B),cnt(C){}
 20     const bool operator ==(const bird & xx)const{
 21         return abs(b/xx.b-a/xx.a)<lit;
 22     }
 23 }b[500];
 24 int finish[(1<<18)+5];
 25 struct Node{
 26     DB x,y;
 27     
 28     inline bool okbird(const bird &k){
 29         return abs(k.a*x*x+k.b*x-y)<lit;
 30     }
 31     
 32 }a[20];
 33 inline bool judge(Node a1,Node a2){
 34     DB x=a1.x-a2.x;
 35     DB y=a1.y/a1.x-a2.y/a2.x;
 36     if(abs(y)<lit || abs(x)<lit || x*y>0)return 0;//无解 或者 无数解 或者 a>0
 37     return 1;
 38 }
 39 inline bird get_ans(Node a1,Node a2){
 40     DB x=a1.x-a2.x;
 41     DB y=a1.y/a1.x-a2.y/a2.x;
 42     DB ansa=y/x;
 43     DB ansb=a1.y/a1.x-ansa*a1.x;
 44     return bird(ansa,ansb);
 45 }
 46 inline int read(){
 47     int a=0;char x=getchar();
 48     while(x<'0'||'9'<x)x=getchar();
 49     while('0'<=x && x<='9'){
 50         a=(a<<1)+(a<<3)+x-'0';
 51         x=getchar();
 52     }
 53     return a;
 54 }
 55 int t,n,m;
 56 int f[(1<<18)+5];
 57 bool gunk[20];
 58 
 59 int main(){
 60     //freopen("angrybirds.in","r",stdin);
 61     //freopen("angrybirds.out","w",stdout);
 62     t=read();
 63     for(int T=1;T<=t;T++){
 64         n=read();m=read();
 65         
 66         memset(gunk,0,sizeof(gunk));
 67         //memset(finish,0,sizeof(finish));
 68         for(int i=1;i<=n;i++)scanf("%lf%lf",&a[i].x,&a[i].y);
 69         //if(n==2){printf(judge(a[1],a[2]) ? "1\n" : "2\n" );continue;}
 70         //for(int i=1;i<=n;i++)printf("%lf %lf\n",a[i].x,a[i].y); 
 71         p=0;
 72         for(int i=1;i<n;i++)
 73             for(int j=i+1;j<=n;j++)
 74             //printf("i%d j%d:",i,j);
 75             //printf("%d\n",judge(a[i],a[j]));
 76             
 77                 if(judge(a[i],a[j])){
 78                 b[p]=get_ans(a[i],a[j]);
 79                 
 80                 for(int k=1;k<=n;k++){
 81                     //printf("%d %d ",k,a[k].okbird(b[p]));
 82                     if(a[k].okbird(b[p]))b[p].cnt|=(1<<(k-1)),gunk[k]=1;
 83                 }
 84             //printf("%d",b[p].cnt);
 85             
 86             if(finish[b[p].cnt]!=T){
 87                     finish[b[p].cnt]=T;
 88                     p++;
 89                 }
 90             }
 91         
 92         for(int i=1;i<=n;i++)if(!gunk[i])b[p++].cnt=1<<(i-1);
 93         
 94         memset(f,0x3f,sizeof(f));
 95         f[0]=0;
 96         for(int s=0;s<(1<<n);s++){
 97             for(int k=0;k<p;k++)f[s|b[k].cnt]=min(f[s|b[k].cnt],f[s]+1);
 98         }
 99         printf("%d\n",f[(1<<n)-1]);
100     }
101     return 0;
102 }
103 /*
104 1
105 2 0
106 1.00 3.00
107 3.00 3.00
108 */
angrybirds

 !!!但是数据强的话还是不行,于是就产生了O(T*n*2^n)的正解!!!

摘抄自某位dalao的blog

在此发一篇严格 O(Tn2^n) 的完全严谨正解。

设计dp状态:

n\le 18n18?不是暴搜就是状压。

dp[S]dp[S] 表示已经死了的猪的集合状态为 SS 时最少要发射的鸟数。

明显有

  • dp[0]=0
  • dp[S|line[i][j]]=dp[Sline[i][j]]=min(dp[S]+1)
  • dp[S|(1<<(i-1)]=dp[S(1<<(i1)]=min(dp[S]+1)

其中 line[i][j] 表示经过 i,j 两点的抛物线能经过的所有点的集合。

这就是网上大多流传的 O(Tn^2*2^n) 算法。优化?

优化1:

发现当 iS 或者 jS 时没有必要转移。

证明:

  • 若这条线只经过至多三个点,因为其中一个点已被打到,所以可以通过另外两个点的状态转移。如果 i,j 都被打到,则可以通过转移3(单独一个点)转移。
  • 若这条线经过多于三个点,则可以通过其它任选两个点转移。

但是这只能算是常数优化。

优化2:

若令 x为满足 S&(1<<(x-1))=0的最小正整数,则由 S 扩展的转移的所有线都要经过 x。

为什么?这个是对的吗?不经过 x 就会慢吗?

你想一想,先打 1,4,再打 2,3,和先打 2,3,再打 1,4 是不是一样的?

如果这一次转移不打 x,那以后还要再回过头来打 x。这就是多余的转移。

因为经过 x 的线数量是 n,所以每次转移涉及到的线就从 n^2 变成了 n

只要预处理一下 0-2^18的对应的 x 就能做到 O(Tn*2^n) 了,这才是考场的正解。

似乎比暴搜还快一点~

code:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const double eps=1e-8;
 4 int t,n,m,lines[20][20],lowunbit[1<<20],dp[1<<20];  //lowunbit就是题解中的x
 5 double x[20],y[20];
 6 void equation(double &x,double &y,double a1,double b1,double c1,double a2,double b2,double c2){ //解方程
 7     y=(a1*c2-a2*c1)/(a1*b2-a2*b1);
 8     x=(c1-b1*y)/a1;
 9 }
10 int main(){
11     for(int i=0;i<(1<<18);i++){ //预处理lowunbit
12         int j=1;
13         for(;j<=18 && i&(1<<(j-1));j++);
14         lowunbit[i]=j;
15     }
16     scanf("%d",&t);
17     while(t--){
18         memset(lines,0,sizeof(lines));  //各种初始化
19         memset(dp,0x3f,sizeof(dp));
20         dp[0]=0;
21         scanf("%d%d",&n,&m);
22         for(int i=1;i<=n;i++) scanf("%lf%lf",x+i,y+i);
23         for(int i=1;i<=n;i++)
24             for(int j=1;j<=n;j++){  //处理所有抛物线
25                 if(fabs(x[i]-x[j])<eps) continue;   //x坐标相同,不可能有解
26                 double a,b;
27                 equation(a,b,x[i]*x[i],x[i],y[i],x[j]*x[j],x[j],y[j]);
28                 if(a>-eps) continue;    //解出a和b
29                 for(int k=1;k<=n;k++)
30                     if(fabs(a*x[k]*x[k]+b*x[k]-y[k])<eps) lines[i][j]|=(1<<(k-1));
31             }
32         for(int i=0;i<(1<<n);i++){  //重点!状压开始!
33             int j=lowunbit[i];  //必须经过lowunbit这个点
34             dp[i|(1<<(j-1))]=min(dp[i|(1<<(j-1))],dp[i]+1); //单独转移
35             for(int k=1;k<=n;k++) dp[i|lines[j][k]]=min(dp[i|lines[j][k]],dp[i]+1); //所有经过lowunbit的抛物线
36         }
37         printf("%d\n",dp[(1<<n)-1]);    //答案
38     }
39 }
amazing Code

summarize:

1.关键还是无用状态的简化与省略

2.利用好题里的限制条件 & 联想之前做过的题目(D2T2)

3.不要因为D1发挥不好而影响D2,难题都会有,暴力分打满就可以了

4.不要沉迷于想正解,往往想完了没时间打

5.学会这种枚举的方式,往往一些题目会用的上

qzh亲传linux调试神器(检查数组越界 & 爆int 等)

-ftrapv -fsanitize=address

 

posted @ 2019-08-31 23:12  Tj1  阅读(189)  评论(0编辑  收藏  举报