博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Nowcoder 提高组练习赛-R2
阅读量:4326 次
发布时间:2019-06-06

本文共 3367 字,大约阅读时间需要 11 分钟。

 

  T1:

  题意概述:对于一个序列,求把序列中的每一个数删去后的新方差*长度的平方.

  良心T1,送分送温暖,把方差的式子化开,O(n)就可以解决. 

  
1 # include 
2 # include
3 # define R register int 4 5 using namespace std; 6 7 const int maxn=100005; 8 int n; 9 long long a[maxn],s,ss,x,y,z;10 11 int main()12 {13 scanf("%d",&n);14 for (R i=1;i<=n;++i)15 scanf("%lld",&a[i]),s+=a[i],ss+=a[i]*a[i];16 for (R i=1;i<=n;++i)17 {18 x=(ss-a[i]*a[i])*(n-1);19 y=(s-a[i])*(s-a[i]);20 if(i!=n) printf("%lld ",x-y);21 }22 printf("%lld\n",x-y);23 return 0;24 }
A

   

  T2:

  题意概述:$N$个小朋友围成一圈,你有无穷个糖果,想把其中一些分给他们。从某个小朋友开始,我们顺时针给他们标号为$1~N$。第$i$个小朋友可以得到至多$a_i$,至少$1$个糖果。问,有多少种分配方案使得每一对相邻的小朋友拿到的糖果数不同。答案对$10^9+7$取模。

  

  良心的T1反衬了T2的不良心.这道题在拿部分分的道路上设置了层层阻碍,比如说前十分的$a_i$实测极大,根本不能用后$30$分的方法来做.

  考虑一个简单的$dp_ij$表示从$1$号小朋友开始发糖,发到第$i$个,且给第$i$个发了$j$个的方案数,因为$n$个人围成一个圈,所以要注意第$1$个人和第$n$个人的糖数也不能相同,可以枚举第一个人拿到的数量.

  对于$a_i$全部相等的情况,可以先不考虑首尾不相等的情况,用$f_i$表示$i$个人发糖的方案数,$f_i=m*(m-1)^{i-1}$,如果首尾相同,则可以把这两个人视为同一个,这样的方案数就成了$f_{i-1}$,递推求解,然而忘开$long long$导致分数只有30.

  
1 # include 
2 # include
3 # include
4 # define mod 1000000007 5 # define R register int 6 7 using namespace std; 8 9 const int maxn=1000005;10 int n,m;11 int a[maxn];12 long long dp[105][105],s[105],ans,f[maxn],t=1;13 14 int main()15 {16 scanf("%d",&n);17 for (R i=1;i<=n;++i)18 scanf("%d",&a[i]);19 if(n>100)20 {21 m=a[1];22 f[1]=m%mod;23 f[2]=(1LL)*m*(m-1)%mod;24 t=(1LL)*(m-1)*(m-1)%mod;25 for (R i=3;i<=n;++i)26 {27 f[i]=((((1LL)*m*t-f[i-1])%mod+mod)%mod);28 t=(1LL)*t*(m-1)%mod;29 }30 printf("%lld",f[n]);31 return 0;32 }33 for (R i=1;i<=a[1];++i)34 {35 memset(dp,0,sizeof(dp));36 memset(s,0,sizeof(s));37 dp[1][i]=1;38 s[1]=1;39 for (R j=2;j<=n;++j)40 {41 for (R k=1;k<=a[j];++k)42 {43 dp[j][k]=((s[j-1]-dp[j-1][k])%mod+mod)%mod;44 if(j==n&&k==i) continue;45 s[j]=(s[j]+dp[j][k])%mod;46 }47 }48 ans=(ans+s[n])%mod;49 }50 printf("%lld",ans);51 return 0;52 }
B

 

  T3:

  题意比较复杂...

  打了一个搜索,得了十分.  

  
1 # include 
2 # include
3 # define R register int 4 5 using namespace std; 6 7 const int maxs=300005; 8 int n,m,k,x; 9 int a[maxs];10 bool f=false;11 int s[maxs];12 int t[maxs],ans[maxs];13 14 void check ()15 {16 for (R i=1;i<=k;++i)17 for (R j=1;j<=k;++j)18 if(s[ t[i]|t[j] ]==false) return;19 f=true;20 for (R i=1;i<=k;++i)21 ans[ t[i] ]=1;22 }23 24 void dfs (int las,int cnt)25 {26 if(f) return ;27 if(cnt==k) check();28 else29 {30 for (R i=las;i<=(1<
k)55 {56 printf("-1");57 return 0;58 }59 for (R i=1;i<=m;++i)60 t[i]=a[i];61 dfs(1,m);62 if(f)63 for (R i=1;i<=(1<
C

  这道题的正解很神奇,是一个状压dp,给每个元素一个优先级,则每个集合的特征就是这个集合中优先级最高的元素,把同样特征的集合都给一个人肯定是合法的,事实上也是构成答案的一个必需条件,问题就在于怎么分使得正好有一部分特征的集合数量总和等于要求的数量.当$k$等于$0$时,可以用$lowbit$来定义集合的优先级,这样每个优先级的集合个数就正好是$2^k$,且不会重复,显然可以用他们凑出任意所需大小的数字来.

  

---shzr

转载于:https://www.cnblogs.com/shzr/p/9671720.html

你可能感兴趣的文章
POJ:1703-Find them, Catch them(并查集好题)(种类并查集)
查看>>
HDU:5040-Instrusive
查看>>
校验器
查看>>
thread/threading——Python多线程入门笔记
查看>>
linux 命令汇总(搜索、fdfs、常用命令),虚拟机dump文件
查看>>
Nginx 反向代理解决浏览器跨域问题
查看>>
为什么现在我最终推荐内存OLTP
查看>>
git error: failed to push some refs to...
查看>>
Markdown指南
查看>>
influxDB的安装和简单使用
查看>>
JPA框架学习
查看>>
JPA、JTA、XA相关索引
查看>>
机器分配
查看>>
php opcode缓存
查看>>
springcloud之Feign、ribbon设置超时时间和重试机制的总结
查看>>
Go 结构体
查看>>
LINQ巩固
查看>>
观看杨老师(杨旭)Asp.Net Core MVC入门教程记录
查看>>
优化后的二次测试Miller_Rabin素性测试算法
查看>>
内部类。
查看>>