1. 程式人生 > >10.10 上午 考試

10.10 上午 考試

sin string 發現 ron line splay $1 getch code

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; }
T1

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());
    }

}
T2

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);
    }
}
T3

總結:

考試的時候,一定要努力想,不要腦子抽風...

10.10 上午 考試