CCPC-WFinal-女生专场

1001:CCPC直播   字符串处理,几个if语句

1002:口算训练   前缀和处理<=根号n的因数,大于根号n的因数每个数至多有一个,用vector存下每个大因数的位置,map离散化。查询的时候lower_bound看是否存在即可。

1003:缺失的数据范围   式子单调增,二分答案。防溢出,需要double。

1004:寻宝游戏   神奇dp  dp[i][j][x][y]表示走到(i,j)位置,有x个已经过的格子未统计,y个未经过的格子统计了的最大总分。往右和往下走的时候分别转移。往下走转移时,要从大到小选取这一行末及下一行首未经过的若干统计。

#include<bits/stdc++.h>
using namespace std;
int read()
{
   int x=0,f=1;char ch=getchar();
   while (ch<'0'||ch>'9') {if (ch=='-') f=-1;ch=getchar();}
   while (ch>='0'&&ch<='9') x=(x<<1)+(x<<3)+ch-'0',ch=getchar();
   return x*f;
}
const int N=55;
int n,m,k,a[N][N],b[N][N][N],f[N][N][22][22],sum,ans,tmp;
vector<int> vec[N];
void Max(int &x,int y){x=max(x,y);}
bool cmp(int A,int B){return A>B;}
int main()
{
    int T=read();
    while (T--)
    {
        n=read();m=read();k=read();
        for (int i=1;i<=n;i++) vec[i].clear();
        memset(b,0,sizeof(b));
        for (int i=1;i<=n;i++)
          for (int j=1;j<=m;j++) {
                a[i][j]=read();if (i==1) continue;
                for (int k=1;k<j;k++) b[i][j][++*b[i][j]]=a[i][k];
                for (int k=j+1;k<=m;k++) b[i][j][++*b[i][j]]=a[i-1][k];
                sort(b[i][j]+1,b[i][j]+*b[i][j]+1,cmp);
          } 
        memset(f,-1,sizeof(f));
        f[1][1][0][0]=0;
        for (int i=1;i<=n;i++)
          for (int j=1;j<=m;j++)
            for (int k1=0;k1<=k;k1++)
              for (int k2=0;k2<=k;k2++)
              if (tmp=f[i][j][k1][k2],tmp!=-1)
              {
                  if (j!=m||i==n)//right
                  {
                      Max(f[i][j+1][k1+1][k2],tmp);
                      Max(f[i][j+1][k1][k2],tmp+a[i][j]);
                    }
                    if (i!=n)//down
                    {
                        sum=0;
                        for (int z=0;z<=k-k2;z++)
                          sum+=z==0?0:b[i+1][j][z],
                          Max(f[i+1][j][k1+1][k2+z],tmp+sum),
                          Max(f[i+1][j][k1][k2+z],tmp+a[i][j]+sum);
                    }
                }
        ans=0;
        for (int k1=0;k1<=k;k1++)
            Max(ans,f[n][m+1][k1][k1]);
        printf("%d\n",ans);
    }
   return 0;
}
View Code

1005:奢侈的旅行  cost=log((level+a[i])/level),那么sigma_cost=log((1+a1)/1)+log((1+a1+a2)/(1+a1))+log((1+a1+a2+a3)/(1+a1+a2))+...,

根据log的变换,sigma_cost=log(1+a1+a2+...+ak)。要使得sigma_cost最小,即使得所有经过的ai之和最小。而每一条边cost>=bi,即level(也就是ai前缀和)<=ai/(2^bi-1),所以ai之和越小越好啦,跟上一个限制的目的一样。

按照ai跑个最短路,走每一条边的时候看限制是否通过即可。(现场大脑死机没想出log的转换,回家种地T_T)

1006:对称数  莫队+分块真的是可以过的啦,括号序列版多了两倍常数就光荣TLE了,以后树分块还是写直接分块、树上跳跃、然后去掉lca、查询时要特判的版本吧。(一开始想莫队+set,没有算好复杂度,结果后来没有时间改掉括号序列,一个是时间复杂度算得不够仔细,一个是转思路不够快)。莫队复杂度现场推,卡均值还是TTT。

正解似乎是某种套路。主席树+二分。出现不出现相当于异或。当权值区间[l,r]中实际的权值异或和=w[l]^w[l+1]^...^w[r](全取1次的异或和),那么大概率[l,r]中的权值都出现奇数次(w为随机权值,小概率被卡)。

猜你喜欢

转载自www.cnblogs.com/Scx117/p/9102301.html