10.10 上午 考试
Posted A_LEAF
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了10.10 上午 考试相关的知识,希望对你有一定的参考价值。
T1
40:
深搜
60:
m<=$10^5$时,可以dp,f[i]表示前i个星球最多的矿
f[i]=max(f[i-4],f[i-7])+val[i]
100:
打表发现只有 1 2 3 5 6 9 10 13 17 不能由4、7组合出来
所以只要把>18的距离离散成18,还像60那样dp就行了
$O(18n)$
#include <cstdio> #include <cstring> #include <cstdlib> #include <iostream> #include <cmath> #include <algorithm> #define mem(a,b) memset(a,b,sizeof(a)) #define ll long long using namespace std; inline int read() { char q=getchar();int ans=0; while(q<‘0‘||q>‘9‘)q=getchar(); while(q>=‘0‘&&q<=‘9‘){ans=ans*10+q-‘0‘;q=getchar();} return ans; } const int N=100006; struct JI { int pos,val; bool friend operator < (JI a,JI b) { return a.pos<b.pos; } }ji[N]; int n,m; int f[N*20],hh[N*20]; int ans; int len; void chu() { sort(ji+1,ji+1+n); int las=0,temp; for(int i=1;i<=n;++i) { if(ji[i].pos-ji[i-1].pos>17) temp=18; else temp=ji[i].pos-ji[i-1].pos; hh[las+temp]+=ji[i].val; las+=temp; } len=las; } void work() { int temp; mem(f,-60); f[0]=0; for(int i=0;i<=len;++i) { if(f[i]<-1000) continue; if(f[i+4]<f[i]+hh[i+4]) f[i+4]=f[i]+hh[i+4]; if(f[i+7]<f[i]+hh[i+7]) f[i+7]=f[i]+hh[i+7]; } for(int i=0;i<=len;++i) if(ans<f[i]) ans=f[i]; } int main(){ n=read();m=read(); for(int i=1;i<=n;++i) ji[i].val=read(),ji[i].pos=read(); chu(); work(); cout<<ans; }
T2
Aavg 平均数
原式可以化简:
$$ (n+m-1)\sum_{i=1}^{n+m-1}(A_i-Aavg)^2$$
$$ ((n+m-1)\sum_{i=1}^{n+m-1}A_{i}^{2})-sum^2$$
定义f[i][j][k] 为i行j列当前sum=k时$A_{i}^2$的最小值
然后从f[i-1][j][k]和f[i][j-1][k]转移就行了
#include <cstdio> #include <cstring> #include <cstdlib> #include <iostream> #include <cmath> #include <algorithm> #define mem(a,b) memset(a,b,sizeof(a)) #define ll long long #define dd double using namespace std; const int N=36; int T; int n,m,sum; int a[N][N]; int f[33][33][27066]; int work() { mem(f,60); int qqq=f[0][0][0]; int hhh=n+m-1,temp; f[1][0][0]=0; for(int i=1;i<=n;++i) for(int j=1;j<=m;++j) for(int k=a[i][j];k<=sum;++k) { if(f[i-1][j][k-a[i][j]]!=qqq) { temp=f[i-1][j][k-a[i][j]]+hhh*a[i][j]*a[i][j]; if(f[i][j][k]>temp) f[i][j][k]=temp; } if(f[i][j-1][k-a[i][j]]!=qqq) { temp=f[i][j-1][k-a[i][j]]+hhh*a[i][j]*a[i][j]; if(f[i][j][k]>temp) f[i][j][k]=temp; } } int ans=0x7fffffff; for(int i=a[n][m];i<=sum;++i) if(f[n][m][i]!=qqq) { temp=f[n][m][i]-i*i; if(ans>temp) ans=temp; } return ans; } int main(){ //freopen("T2.in","r",stdin); //freopen("T2.out","w",stdout); scanf("%d",&T); while(T--) { scanf("%d%d",&n,&m); sum=0; for(int i=1;i<=n;++i) for(int j=1;j<=m;++j) { scanf("%d",&a[i][j]); sum+=a[i][j]; } printf("%d\n",work()); } }
T3
M是非常小的,所以异或之后受影响的只是低位,再dfs的时候记录下来低位是那个的个数即可
(我还在想异或会不会有什么结合律之类的...)
#include <cstdio> #include <cstring> #include <cstdlib> #include <iostream> #include <cmath> #include <algorithm> #define mem(a,b) memset(a,b,sizeof(a)) #define ll long long using namespace std; inline int read() { char q=getchar();int ans=0; while(q<‘0‘||q>‘9‘)q=getchar(); while(q>=‘0‘&&q<=‘9‘){ans=ans*10+q-‘0‘;q=getchar();} return ans; } const int N=100006; struct son { int v,next,w; }a1[N*2]; int first[N*2],e; void addbian(int u,int v,int w) { a1[e].v=v; a1[e].w=w; a1[e].next=first[u]; first[u]=e++; } int n,M,mod; int gget() { int tt=M; while(tt!=(tt&(-tt))) tt-=(tt&(-tt)); return tt<<1; } int fa[N],sh[N][21],xi[N][21]; int xihe[N],shhe[N],size[N]; int t[21]; void dfs1(int x) { int temp; size[x]=1; for(int i=first[x];i!=-1;i=a1[i].next) { temp=a1[i].v; if(temp==fa[x]) continue; fa[temp]=x; dfs1(temp); size[x]+=size[temp]; xihe[x]+=(xihe[temp]+a1[i].w*size[temp]); mem(t,0); ++t[a1[i].w%mod]; for(int j=0;j<mod;++j) t[(j+a1[i].w)%mod]+=xi[temp][j]; for(int j=0;j<mod;++j) xi[x][j]+=t[j]; } } int bb[21]; void dfs2(int x) { int temp; for(int i=first[x];i!=-1;i=a1[i].next) { temp=a1[i].v; if(temp==fa[x]) continue; shhe[temp]+=(shhe[x]+xihe[x]-(xihe[temp]+a1[i].w*size[temp])+(size[1]-size[temp])*a1[i].w); mem(t,0);mem(bb,0); ++t[a1[i].w%mod]; for(int j=0;j<mod;++j) t[(j+a1[i].w)%mod]+=xi[temp][j]; for(int j=0;j<mod;++j) t[j]=(xi[x][j]-t[j]+sh[x][j]); ++bb[a1[i].w%mod]; for(int j=0;j<mod;++j) bb[(a1[i].w+j)%mod]+=t[j]; for(int j=0;j<mod;++j) sh[temp][j]=bb[j]; dfs2(temp); } } int main(){ //freopen("T3.in","r",stdin); mem(first,-1); n=read();M=read(); mod=gget(); if(mod==0)mod=1; int tin1,tin2,tin3; for(int i=1;i<n;++i) { tin1=read();tin2=read();tin3=read(); addbian(tin1,tin2,tin3); addbian(tin2,tin1,tin3); } dfs1(1); dfs2(1); int temp; for(int i=1;i<=n;++i) { temp=shhe[i]+xihe[i]; for(int j=0;j<mod;++j) temp+=(sh[i][j]+xi[i][j])*((j^M)-j); printf("%d\n",temp); } }
总结:
考试的时候,一定要努力想,不要脑子抽风...
以上是关于10.10 上午 考试的主要内容,如果未能解决你的问题,请参考以下文章