这个NOI模拟题怕是比你们的NOIp模拟题要简单哦。。
友好的生物
应该是一道简单题,但是机房只有辉神一个人想到正解似乎。
被我kd-tree水过去了(这不是kd-tree的裸题吗???(不是))
1 //Achen
2 #include<bits/stdc++.h>
3 #define For(i,a,b) for(int i=(a);i<=(b);i++)
4 #define Rep(i,a,b) for(int i=(a);i>=(b);i--)
5 #define Formylove return 0
6 #define inf 1e18
7 const int N=100007;
8 using namespace std;
9 typedef long long LL;
10 typedef double db;
11 int n,K,D;
12 LL C[10],ans;
13
14 template<typename T>void read(T &x) {
15 T f=1; x=0; char ch=getchar();
16 while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
17 if(ch=='-') f=-1,ch=getchar();
18 for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
19 }
20
21 struct node {
22 int d[5];
23 friend bool operator <(const node&A,const node&B) {
24 return A.d[D]<B.d[D];
25 }
26 }p[N],q[N],T;
27
28 void get_min(int &x,int y) { if(x>y) x=y; }
29 void get_max(int &x,int y) { if(x<y) x=y; }
30
31 int rt,ch[N][2],dt[N][5][2];
32 #define lc ch[x][0]
33 #define rc ch[x][1]
34 #define mid ((l+r)>>1)
35 void update(int x,int l,int r) {
36 For(i,0,K-1) dt[x][i][0]=dt[x][i][1]=p[x].d[i];
37 if(lc) For(i,0,K-1) {
38 get_min(dt[x][i][0],dt[lc][i][0]);
39 get_max(dt[x][i][1],dt[lc][i][1]);
40 }
41 if(rc) For(i,0,K-1) {
42 get_min(dt[x][i][0],dt[rc][i][0]);
43 get_max(dt[x][i][1],dt[rc][i][1]);
44 }
45 }
46
47 int build(int l,int r,int k) {
48 if(l>r) return 0;
49 D=k;
50 sort(p+l,p+r+1);
51 int x=((l+r)>>1);
52 lc=build(l,x-1,(k+1)%K);
53 rc=build(x+1,r,(k+1)%K);
54 update(x,l,r);
55 return x;
56 }
57
58 void get_ans(int x) {
59 LL rs=0;
60 For(i,0,K-2) rs+=abs(p[x].d[i]-T.d[i])*C[i];
61 rs-=abs(p[x].d[K-1]-T.d[K-1])*C[K-1];
62 ans=max(ans,rs);
63 }
64
65 LL guess_min(int x) {
66 LL rs=0;
67 For(i,0,K-2) {
68 if(dt[x][i][0]<=T.d[i]&&dt[x][i][1]>=T.d[i]) continue;
69 if(T.d[i]<dt[x][i][0]) rs+=(dt[x][i][0]-T.d[i])*C[i];
70 else rs+=(T.d[i]-dt[x][i][1])*C[i];
71 }
72 rs-=max(abs(T.d[K-1]-dt[x][K-1][0]),abs(T.d[K-1]-dt[x][K-1][1]))*C[K-1];
73 return rs;
74 }
75
76 LL guess_max(int x) {
77 if(!x) return -inf;
78 LL rs=0;
79 For(i,0,K-2) {
80 rs+=max(abs(T.d[i]-dt[x][i][0]),abs(T.d[i]-dt[x][i][1]))*C[i];
81 }
82 if(T.d[K-1]<dt[x][K-1][0]) rs-=(dt[x][K-1][0]-T.d[K-1])*C[K-1];
83 else if(T.d[K-1]>dt[x][K-1][1]) rs-=(T.d[K-1]-dt[x][K-1][1])*C[K-1];
84 return rs;
85 }
86
87 void qry(int x,int l,int r,int k) {
88 if(!x||l>r) return ;
89 get_ans(x);
90 LL lg=guess_max(lc);
91 LL rg=guess_max(rc);
92 if(lg<=ans&&rg<=ans) return ;
93 if(lg>=rg) {
94 qry(lc,l,mid-1,(k+1)%K);
95 if(rg>ans) qry(rc,mid+1,r,(k+1)%K);
96 }
97 else {
98 qry(rc,mid+1,r,(k+1)%K);
99 if(lg>ans) qry(lc,l,mid-1,(k+1)%K);
100 }
101 }
102
103 #define ANS
104 int main() {
105 #ifdef ANS
106 freopen("species.in","r",stdin);
107 freopen("species.out","w",stdout);
108 #endif
109 read(n); read(K);
110 For(i,0,K-1) read(C[i]);
111 For(i,1,n) {
112 For(j,0,K-1) read(p[i].d[j]);
113 q[i]=p[i];
114 }
115 ans=-inf;
116 rt=build(1,n,0);
117 For(i,1,n) {
118 T=q[i];
119 qry(rt,1,n,0);
120 }
121 printf("%lld
",ans);
122 //cerr<<clock()<<endl;
123 Formylove;
124 }
正解:
这个题其实是三道题中最简单的一道。先来看这个问题的一个简化版,假设所有的属性都是差值越大越友好的话:
那么,这个题目会变得简单很多,我们依次枚举在最有情况下,每一种属性值是编号小的动物大,还是编号大的动物大。假设,对于第i种属性,编号小的动物大这种情况用t[i]=-1表示,编号大的动物属性值大这种情况用t[i]=1表示。那么,动物i和动物j的属性值
并且,我们总有一个时刻可以枚举对每一种属性的情况,使等号成立。所以,我们可以通过寻找右侧式子的最大值来确定左侧式子的最大值。
回到本题,题目中的最后一个属性和前面的是反过来的,即差值越小越友好,在这种情况下,我们可以先将动物们按照最后一个属性值来排序,之后按照上面给出的做法实现就可以了。
正解当然优美很多了
1 //Achen
2 #include<bits/stdc++.h>
3 #define For(i,a,b) for(int i=(a);i<=(b);i++)
4 #define Rep(i,a,b) for(int i=(a);i>=(b);i--)
5 #define Formylove return 0
6 #define inf 1e18
7 const int N=100007;
8 using namespace std;
9 typedef long long LL;
10 typedef double db;
11 int n,K,D;
12 LL C[10],ans;
13
14 template<typename T>void read(T &x) {
15 T f=1; x=0; char ch=getchar();
16 while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
17 if(ch=='-') f=-1,ch=getchar();
18 for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
19 }
20
21 struct node {
22 int d[5];
23 friend bool operator <(const node&A,const node&B) {
24 return A.d[K-1]>B.d[K-1];
25 }
26 }p[N];
27
28 #define ANS
29 int main() {
30 #ifdef ANS
31 freopen("species.in","r",stdin);
32 freopen("species.out","w",stdout);
33 #endif
34 read(n); read(K);
35 For(i,0,K-1) read(C[i]);
36 For(i,1,n) {
37 For(j,0,K-1) read(p[i].d[j]);
38 }
39 sort(p+1,p+n+1);
40 LL pr=inf;
41 ans=-inf;
42 int up=(1<<K-1)-1;
43 For(t,0,up) {
44 pr=inf;
45 For(i,1,n) {
46 LL tp=0;
47 For(d,1,K-1) if(t&(1<<d-1)) tp-=C[d-1]*p[i].d[d-1];
48 else tp+=C[d-1]*p[i].d[d-1];
49 ans=max(ans,tp+C[K-1]*p[i].d[K-1]-pr);
50 pr=min(pr,tp+C[K-1]*p[i].d[K-1]);
51 }
52 }
53 printf("%lld
",ans);
54 //cerr<<clock()<<endl;
55 Formylove;
56 }
基因重组
这是个真水题,n^2dp随便怎么做,我做的时候脑子有点抽写得有点奇怪,还用了short卡空间。。但是这个dp随便怎么写都能过吧。
1 //Achen
2 #include<bits/stdc++.h>
3 #define For(i,a,b) for(int i=(a);i<=(b);i++)
4 #define Rep(i,a,b) for(int i=(a);i>=(b);i--)
5 #define Formylove return 0
6 const int N=5007;
7 using namespace std;
8 typedef long long LL;
9 typedef double db;
10 int n,m,up=24400,c1,c2,c3;
11 short s1[N][N],f[N][N],mi[N],ans;
12 LL x;
13 char a[N],b[N],a2[N];
14
15 template<typename T>void read(T &x) {
16 T f=1; x=0; char ch=getchar();
17 while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
18 if(ch=='-') f=-1,ch=getchar();
19 for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
20 }
21
22 void get_min(short &x,int y) { if(x>y) x=y; }
23
24 #define ANS
25 int main() {
26 #ifdef ANS
27 freopen("DNA.in","r",stdin);
28 freopen("DNA.out","w",stdout);
29 #endif
30 read(x); if(x>up) c1=up+1; else c1=x;
31 read(x); if(x>up) c2=up+1; else c2=x;
32 read(x); if(x>up) c3=up+1; else c3=x;
33 scanf("%s",a); n=strlen(a);
34 For(i,0,n-1) {
35 if(a[i]=='A') a2[i]='T';
36 else if(a[i]=='T') a2[i]='A';
37 else if(a[i]=='C') a2[i]='G';
38 else if(a[i]=='G') a2[i]='C';
39 }
40 scanf("%s",b); m=strlen(b);
41 Rep(i,n,1) Rep(j,m,1) {
42 if(a[i-1]==b[j-1]) s1[i][j]=s1[i+1][j+1]+1;
43 else s1[i][j]=0;
44 if(a2[i-1]==b[j-1]) f[i][j]=f[i+1][j+1]+1;
45 else f[i][j]=0;
46 }
47 For(i,1,n) For(j,1,m) s1[i][j]=max(s1[i][j],f[i][j]);
48 memset(f,127,sizeof(f));
49 memset(mi,127,sizeof(mi));
50 mi[0]=0;
51 f[0][0]=0; ans=up;
52 For(i,0,n) {
53 For(j,0,m) {
54 get_min(f[i][j],(int)mi[j]+c2);
55 mi[j]=min(mi[j],f[i][j]);
56 int t=s1[i+1][j+1];
57 get_min(f[i+t][j+t],(int)f[i][j]+c1);
58 if(j==m) get_min(ans,(int)f[i][j]);
59 else get_min(f[i][j+1],(int)f[i][j]+c3);
60 }
61 }
62 printf("%d
",(int)ans);
63 //cerr<<clock()<<endl;
64 Formylove;
65 }
危险的迷宫
好多人切这题啊。。。全机房就我一个人不知道这题是费用流???
这不是一道插头dp的裸题吗????
人类,你们对插头dp一无所知!
作死写了百行转移,结果大样例都没过,交上去还水过了50pt.
然后de了一晚上。。。
一个是有个地方n和m写反了,另外两个是两段轮廓线上一个是1一个是2的时候,如果这个格子本身是1或者2那么是不合法的,不能直接合并清0了!两句话价值一晚上+50pt。
1 //Achen
2 #include<bits/stdc++.h>
3 #define For(i,a,b) for(int i=(a);i<=(b);i++)
4 #define Rep(i,a,b) for(int i=(a);i>=(b);i--)
5 #define Formylove return 0
6 const int N=177148;
7 using namespace std;
8 typedef long long LL;
9 typedef double db;
10 int n,m,K,C,f[12][12][N],inf,pr[30];
11 int a[15][15],is[15][15],rr[15][15],dn[15][15];
12
13 template<typename T>void read(T &x) {
14 T f=1; x=0; char ch=getchar();
15 while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
16 if(ch=='-') f=-1,ch=getchar();
17 for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
18 }
19
20 void GM(int &x,int y) { if(x>y) x=y; }
21 int get(int s,int k) {
22 return s/pr[k-1]%3;
23 }
24
25 #define ANS
26 int main() {
27 #ifdef ANS
28 freopen("maze.in","r",stdin);
29 freopen("maze.out","w",stdout);
30 #endif
31 read(n); read(m);
32 For(i,1,n) For(j,1,m) read(a[i][j]);
33 read(K);
34 For(i,1,K) {
35 int x1,y1,x2,y2;
36 read(x1); read(y1);
37 read(x2); read(y2);
38 if(x1>x2) swap(x1,x2),swap(y1,y2);
39 if(x1<x2) dn[x1][y1]=1;
40 else {
41 if(y1>y2) swap(y1,y2);
42 rr[x1][y1]=1;
43 }
44 }
45 read(C);
46 For(i,1,C) {
47 int x,y;
48 read(x); read(y);
49 is[x][y]=1;
50 }
51 For(i,1,C) {
52 int x,y;
53 read(x); read(y);
54 is[x][y]=2;
55 }
56 /*For(i,1,n) {
57 For(j,1,m) {
58 printf("%d ",rr[i][j]);
59 } puts("");
60 }
61 For(i,1,n) {
62 For(j,1,m) {
63 printf("%d ",dn[i][j]);
64 } puts("");
65 }
66 For(i,1,n) {
67 For(j,1,m) {
68 if(is[i][j]) printf("%d(%d)",a[i][j],is[i][j]);
69 else printf("%d",a[i][j]);
70 }*/
71 pr[0]=1;
72 For(i,1,20) pr[i]=pr[i-1]*3;
73 memset(f,127/3,sizeof(f));
74 inf=f[0][0][0];
75 f[1][1][0]=0;
76 int up=pr[m+1]-1;
77 For(i,1,n) {
78 For(j,1,m) {
79 For(s,0,up) if(f[i][j][s]!=inf) {
80 int prs=s;
81 if(j==1) s*=3;
82 int f1=get(s,j),f2=get(s,j+1);
83 int ii,jj;
84 if(j==m) ii=i+1,jj=1;
85 else ii=i,jj=j+1;
86 if(!f1) {
87 if(!f2) {
88 if(is[i][j]) {
89 if(rr[i][j]) GM(f[ii][jj][s+is[i][j]*pr[j]],f[i][j][prs]+a[i][j]);
90 if(dn[i][j]) GM(f[ii][jj][s+is[i][j]*pr[j-1]],f[i][j][prs]+a[i][j]);
91 }
92 else {
93 GM(f[ii][jj][s],f[i][j][prs]);
94 if(rr[i][j]&&dn[i][j]) {
95 GM(f[ii][jj][s+pr[j-1]+2*pr[j]],f[i][j][prs]+a[i][j]);
96 GM(f[ii][jj][s+2*pr[j-1]+pr[j]],f[i][j][prs]+a[i][j]);
97 }
98 }
99 }
100 if(f2==1) {
101 if(is[i][j]==2)
102 GM(f[ii][jj][s-pr[j]],f[i][j][prs]+a[i][j]);
103 else if(!is[i][j]) {
104 if(rr[i][j]) GM(f[ii][jj][s],f[i][j][prs]+a[i][j]);
105 if(dn[i][j]) GM(f[ii][jj][s+pr[j-1]-pr[j]],f[i][j][prs]+a[i][j]);
106 }
107 }
108 if(f2==2) {
109 if(is[i][j]==1)
110 GM(f[ii][jj][s-2*pr[j]],f[i][j][prs]+a[i][j]);
111 else if(!is[i][j]) {
112 if(rr[i][j]) GM(f[ii][jj][s],f[i][j][prs]+a[i][j]);
113 if(dn[i][j]) GM(f[ii][jj][s+2*pr[j-1]-2*pr[j]],f[i][j][prs]+a[i][j]);
114 }
115 }
116 }
117 else if(f1==1) {
118 if(!f2) {
119 if(is[i][j]==2)
120 GM(f[ii][jj][s-pr[j-1]],f[i][j][prs]+a[i][j]);
121 else if(!is[i][j]) {
122 if(rr[i][j]) GM(f[ii][jj][s-pr[j-1]+pr[j]],f[i][j][prs]+a[i][j]);
123 if(dn[i][j]) GM(f[ii][jj][s],f[i][j][prs]+a[i][j]);
124 }
125 }
126 if(f2==1) ;
127 if(f2==2&&!is[i][j])
128 GM(f[ii][jj][s-pr[j-1]-2*pr[j]],f[i][j][prs]+a[i][j]);
129 }
130 else if(f1==2) {
131 if(!f2) {
132 if(is[i][j]==1)
133 GM(f[ii][jj][s-2*pr[j-1]],f[i][j][s]+a[i][j]);
134 else if(!is[i][j]) {
135 if(rr[i][j]) GM(f[ii][jj][s-2*pr[j-1]+2*pr[j]],f[i][j][s]+a[i][j]);
136 if(dn[i][j]) GM(f[ii][jj][s],f[i][j][s]+a[i][j]);
137 }
138 }
139 if(f2==1&&!is[i][j])
140 GM(f[ii][jj][s-2*pr[j-1]-pr[j]],f[i][j][s]+a[i][j]);
141 if(f2==2) ;
142 }
143 s=prs;
144 if(f[3][4][0]!=inf) {
145 int debug=1;
146 }
147 }
148 }
149 }
150 if(f[n+1][1][0]==inf) puts("-1");
151 else printf("%d
",f[n+1][1][0]);
152 //cerr<<clock()<<endl;
153 Formylove;
154 }