2017.07.15NOIP提高组模拟赛B组总结

t1

  奶牛买了一个奶酪厂生产奶酪,已知每周生产一单位奶酪的费用为C_i,每周可以生产任意数量的奶酪,现在要为接下来N(1<=N<=10,000)周做生产计划。
  厂里有一个仓库,存储量无穷大,可以用来存储暂时不用的奶酪,每单位奶酪每周花费S(1<=S<=100)。
  告诉你每周客户的需求量Y_i(0<=Y_i<=10,000),请你帮忙用最少的钱满足这些需求。


奶酪厂,看上去很好吃。。。。。
好吧,水题一道,不说太多,贪心O(n)果断切,100分到手。

记录一个last,即上一次在第几天做的奶酪,然后枚举i,如果c[i]>c[last]+s*(i-last)则仍然在last天做第i天的奶酪,否则更新last,不论如何都要记得统计ans。


t2

奶牛们想用K(1<=K<=400)中石块制造一个太空电梯去太空旅行,每种石块有自己的高度h_i(1<=h_i<=100)和数量c_i(1<=c_i<=10),为了避免宇宙射线的干扰,每种石块不能超过最高可以达到的高度a_i(1<=a_i<=40000)。
帮助奶牛用石块堆积一个最高的太空电梯。


太空电梯,我除了说它们有病还能说啥。。。。。
看到数据范围,果断dp不解释,虽然我的dp和别人不大一样,不过我还是果断AC了!

首先求出一个max,即a[i] 的最大值,一会儿求答案时要用
设f[i,j]表示当使用前i种石头,达到高度为j所用的最少石块数,dp过程如下

for i:=1 to n do
begin
    f[i]:=f[i-1];
    for k:=1 to c[i] do
        for j:=k*h[i] to a[i] do
            if f[i-1,j-k*h[i]]+k<f[i,j] then
                f[i,j]:=f[i-1,j-k*h[i]]+k;
end;

其中k为第i种石块使用的数量,即可求出符合原意的f[i,j](虽然有点多余,但以后还可以用嘛。。。)。
最后,i从max到1枚举一下,如果f[n,i]不为初始设的那个灰常灰常大的数,即可以到达i这个高度,输出并退出就好了。


t3

小z热衷于数学。
今天数学课的内容是解不等式:L<=S*x<=R。小z心想这也太简单了,不禁陷入了深深的思考:假如已知L、R、S、M,满足L<=(S*x)mod M<=R的最小正整数x该怎么求呢?

30%的数据中保证有解并且答案小于等于10^6;
另外20%的数据中保证L=R;
100%的数据中T<=100,M、S、L、R<=10^9。


好吧我承认我看到这题的时候是一脸懵逼的,完全不知道咋做,草草打个暴力了事
直到我听完题解,我惊奇的发现。。。。。。我还是一脸懵逼。。。。。。。。。
正解我完全没听进去,貌似是类欧几里得算法之类的,有兴趣的同学可以自己去看一下。


t4

小A正在搭积木。有N个位置可以让小A使用,初始高度都为0。小A每次搭积木的时候,都会选定一个拥有相同高度的区间[A..B],然后将位置[A+1..B-1]上的所有积木的高度加一。不幸的是,小A把积木搭好之后没多久,小A调皮的弟弟就将其中若干个位置上的积木弄倒了。小A想知道他原来的积木是如何摆放的,所以他求助于你,请你告诉他原来有多少种可能的摆法。

对于50%的数据 1<=N<=1000 -1<=Hi<=1000
对于80%的数据 1<=N<=10000
对于100%的数据 1<=N<=20000 -1<=Hi<=10000


我只能说,小A和他弟脑子都有毛病。。。。。。
看上去很复杂,数据范围也很大,但由于数据比较水,n^2的dp还是可以过的。
由于n比较大,所以记得要用滚动数组,否则就等着空超吧。

 readln(n);
 for i:=1 to n do
 begin
     read(h[i]);
     if i<=n div 2 then max[i]:=i-1
     else max[i]:=n-i;
 end;
 fillchar(f,sizeof(f),0);
 f[1,0]:=1;
 if (h[1]>0)or(h[n]>0) then
 begin
     writeln(0);
     exit;
 end;
 h[1]:=0;
 h[n]:=0;
 for i:=2 to n do
 begin
     if h[i]>-1 then
     begin
         j:=h[i];
         f[2,j]:=f[1,j-1]+f[1,j]+f[1,j+1];
     end
     else
     begin
         if i mod 10=0 then
             for j:=0 to max[i] do
                 f[2,j]:=(f[1,j-1]+f[1,j]+f[1,j+1]) mod 1000000007 
         else
             for j:=0 to max[i] do
                 f[2,j]:=(f[1,j-1]+f[1,j]+f[1,j+1]) mod 1000000007
     end;
     f[1]:=f[2];
     fillchar(f[2],sizeof(f[2]),0);
 end;
 writeln(f[1,0] mod 1000000007);
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值