zoukankan      html  css  js  c++  java
  • dp乱写3:环形区间dp(数字游戏)

    状态:

    fmax[i,j]//表示前i个数分成j个部分的最大值

    fmin[i,j]//表示前i个数分成j个部分的最小值

    边界:fmax[i,1]:=(sum[i] mod 10+10) mod 10(sum[i]为前i个数的总和);fmin[i,1]:=(sum[i] mod 10+10) mod 10;

    状态转移方程:

    fmax[i,j]:=max(fmax[i,j],fmax[k,j-1]*ff(sum[i]-sum[k]));

    fmin[i,j]:=min(fmin[i,j],fmin[k,j-1]*ff(sum[i]-sum[k]){ff为取sum[i]-sum[k]对10取余的结果});//找一个中间点,把1到k分j-1个部分,而之前我们已经做出了决策,答案保存在f[k,j-1]里,另外k+1到i看成一部分,利用前缀和求出从k+1到i的值。

    处理环:把环看成一条链,旋转出这条环所有的可能性(旋转即把整个数组里的数都往前1格,第一个数则到最后一个位置)

    uses math;
    var  a,sum:array[0..51]of longint;
         fmax,fmin:array[0..51,0..10]of longint;
         n,m,i,j,k,x,maxn,minn,t:longint;
    function ff(x:longint):longint;
    begin
     exit(((x mod 10)+10) mod 10);
    end;
    procedure dp;
    var i,j,k:longint;
    begin
     for i:=1 to n do sum[i]:=sum[i-1]+a[i];
     for i:=0 to n do
      for j:=0 to m do begin
      fmax[i,j]:=-maxlongint div 10;
      fmin[i,j]:=maxlongint div 10;
     end;
     for i:=1 to n do begin
      fmax[i,1]:=ff(sum[i]);
      fmin[i,1]:=ff(sum[i]);
     end;
     for i:=1 to n do
      for j:=2 to m do
       for k:=j-1 to i-1 do begin
        fmax[i,j]:=max(fmax[i,j],fmax[k,j-1]*ff(sum[i]-sum[k]));
        fmin[i,j]:=min(fmin[i,j],fmin[k,j-1]*ff(sum[i]-sum[k]))
       end;
      maxn:=max(maxn,fmax[n,m]);
      minn:=min(minn,fmin[n,m]);
    end;
    begin
     readln(n,m);
     for i:=1 to n do read(a[i]);
     minn:=maxlongint;
     for i:=1 to n do begin
      t:=a[1];
      for j:=1 to n-1 do  a[j]:=a[j+1];
      a[n]:=t;
      dp;
     end;
     writeln(minn);
     writeln(maxn);
    end.
  • 相关阅读:
    wowjs
    权限组件的判断
    跨域
    Github DNS解析失败怎么办?
    GraceUI
    ant vue 组件 cascader 封装地址联动选择器
    js 防抖节流
    SCSS 的基本使用
    使用 nuxt 开发网站 之 如何做国际化?
    使用 nuxt 开发网站 之 如何展示子页面?
  • 原文地址:https://www.cnblogs.com/ljc20020730/p/7346823.html
Copyright © 2011-2022 走看看