聪明伶俐的香穗子(NDK1353)

24 篇文章 0 订阅
聪明伶俐的香穗子


Time Limit:10000MS  Memory Limit:65536K
Total Submit:23 Accepted:14 


Description 


香穗子遇到难题了. 
题目是这样的,一个序列上有n个整数,现在你要取m个,且这m个数的任意两个不能相隔的太近,否则这样会太丑,现在问你最大能得到多大的和 




Input 


第一行三个数n,m,k,分别表示n个数,取m个,且m个中的任意两个位置差要大于等于K 
接下来一行,有n个整数,表示序列上的每个数 






Output 


最大和


Sample Input 




4 2 2
3 4 -5 1




Sample Output 




5


Hint 


数据范围: 
n <= 10000,m <= 100,m <= n 
答案保正小于 Maxlongint 




Source 


NOIdaokan


算法:DP


四道题里面唯一有点档次的题目了……
一开始想的是一个三重的循环,用f[i,j]表示前i个数里面选j个数能取得的最大和,然后从前面找个最优状态更新,结果果断超时,考完试下来之后才猛然发现,尼玛最优的状态不就是i-mm么(因为每次更新找的都是最优状态,因此最优状态只能是i-mm),这个坑爹的说,原来只要把最后的那层循环删掉就AC了的说。。。。

注意初始化,题目中有负值,因此fillchar为200,然后把前i项里面选0个的状态标记成0。

program p4;

const
 maxn=10000;
 maxm=100;

var
 n,m,mm:longint;
 a,maxx:array [0..maxn] of longint;
 f:array [-maxn..maxn,0..maxm] of longint;

procedure init;
var
 i:longint;
begin
 readln(n,m,mm);
 for i:=1 to n do read(a[i]);
end;

procedure main;
var
 i,j,k:longint;
begin
 fillchar(f,sizeof(f),200);
 for i:=-maxn to n do f[i,0]:=0;
 for i:=1 to n do
  begin
   for j:=1 to m do
    begin
     f[i,j]:=f[i-1,j];
     if f[i-mm,j-1]+a[i]>f[i,j] then f[i,j]:=f[i-mm,j-1]+a[i];
    end;
  end;
end;

begin
 assign(input,'4.in'); reset(input);
 assign(output,'4.out'); rewrite(output);

 init;
 main;
 writeln(f[n,m]);

 close(input); close(output);
end.                         


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值