zoukankan      html  css  js  c++  java
  • war2 洛谷模拟赛day2 t3 状压

    (new )   war2

    题解:总体数据而言N leq 18,我们很容易想到着就是DP啊,我们DP数组f[i][j],i用状态压缩,代表有那些点已经被占领过了,j代表上一次我占的是那个。对于每一次状态转移,若当前我们要占领的Portal在占领j后有加分,那么就转移加分与基础值的和,否则只转移基础值。最后判断一下当i代表的状态已经有占领m个了,就记录下当前的最大值。

    var
    n,m,tot,cnt,ans,x,y,c:int64;
    i,j,k:longint;
    a:array[-100..100]of int64;
    f,b:array[0..1<<18,0..20]of int64;// 2^18
    function max(x,y:int64):int64;
     begin
      if x>y then exit(x) else exit(y);
     end;
    begin
    readln(n,m,k);
    for i:=1 to n do read(a[i]);
    readln;
    for i:=1 to k do
    begin
     readln(x,y,c);
     inc(b[x,y],c);
    end;
    for i:=1 to n do
     f[1<<(i-1)][i]:=a[i];
     tot:=(1<<n)-1;
      for k:=0 to tot do //every state
       begin
        cnt:=0;
        for i:=1 to n do
          begin
            if ((1<<(i-1)) and k)>0 then
              begin
                inc(cnt);
               //  if k=7 then writeln(i,' ',cnt);
                // writeln(cnt);
                 for j:=1 to n do
                  if (1<<(j-1))and k=0 then 
                   f[k or (1<<(j-1))][j]:=max(f[k or (1<<(j-1)) ][j],f[k,i]+b[i,j]+a[j]);// 1000-->1100,当前点占了所得到的值
              end;
          end;
        if cnt=m then
         begin
           for i:=1 to n do
             if k and (1<<(i-1))>0 then ans:=max(ans,f[k,i]);
             // writeln(cnt);
         end;
        end;
     writeln(ans);
     end.
    NOIP2018 rp++
  • 相关阅读:
    c语言字符串_续
    c语言中文件的操作
    Linux基础知识
    netstat
    wireshark 过滤规则
    常用cmd命令
    优化过的redis封装类
    二十三岁,新的起点
    计划看的书目
    [转载]爱上一个给予你正能量的人
  • 原文地址:https://www.cnblogs.com/brilliant107/p/9751261.html
Copyright © 2011-2022 走看看