首页 > 其他 > 详细

AGC041D Problem Scores(DP)

时间:2020-02-14 21:49:50      阅读:122      评论:0      收藏:0      [点我收藏+]

这场比赛由 tourist出题。%。比赛链接: agc041

题意

给一个长度为\(n\)的序列赋整数值,赋值的值域范围\([1,n]\)。要求赋值后的序列非递减,且对于\(1\le k\le {n-1}\),从序列中任取\(k+1\)个数要比任取\(k\)个数的和大。问有多少种赋值方式?

题解

一共有\(n-1\)个限制条件,但是通过观察可以发现,只要满足\(k=n/2\)时的条件,其他条件自动满足。

要求序列满足非递减,因此考虑使用如下方式表示序列中的数字:

\(A_i = 1+x_1+x_2+...+x_i\)\(x\ge0\)

根据题意转换\(x\)要满足以下条件:

  • \(x_1+x_2+x_3+...+x_n \le n-1\),值域限制
  • \(x_1 \ge [x_2,x_3,...,x_n]·[0,1,2,...,2,1]\),‘·’表示点乘,由满足\(k=n/2\)时条件带入推出。

此时若固定\(x_2,x_3,...,x_n\)的值,可以得出\(x_1\)\(max(n-[x_2,x_3,...,x_n]·[1,2,3,...,3,2])\)

因此问题变成枚举每种点乘和有多少个。可以用\(DP\)解决。

\(dp[i]\)表示和为\(i\)的有多少种。

初始状态\(dp[0]=1\)

转移的时候有个技巧,由于增加的数字是某个数的倍数,设倍数是\(w\),朴素的转移需要对\([0,w,w*1,w*2,w*3...]\)都做一遍转移,且\(dp\)要两维,但可以用如下方式简单转移:

for(int j=w;j<n;++j)
    dp[j]+=d[j-w];

不能理解的,用具体数字写一个转移就可以体会其中的巧妙。

AGC041D Problem Scores(DP)

原文:https://www.cnblogs.com/gooooooo/p/12309528.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!