当前位置: 代码迷 >> 综合 >> 3067. 【NOIP2012模拟10.29晚】密码盘 (Standard IO)
  详细解决方案

3067. 【NOIP2012模拟10.29晚】密码盘 (Standard IO)

热度:61   发布时间:2023-10-09 12:00:09.0

Description

 

 

 

 

【问题描述】

 

 

如图是某人设想中的N×N的密码盘,用以显示自己强大的智商以及计算能力。图中每列上面有一个01的值,每行左边也有一个01的值。密码盘中有最多N*N个按钮,每个按钮有一个数值。按钮按下去之后,你会获得按钮上的分数,然后对应行和对应列的值会改变。

 

 

例如:假设按钮(14)的数值为k,按下它,你获得k分,然后第一行的1会变成0,第四列的0会变成1

 

 

你的任务是,使每列上面的值和每行左边的值一一对应相等(从左到右和从上到下),并且取得最大的积分。当然了初始积分为0

 

 

 

Input

 

 

 

 

【输入】

 

 

输入文件名为mima.in

 

 

第一行一个正整数N,表示密码盘的大小。N最大为9

 

 

第二行一个01串,表示从上到下每行左边的N个值。

 

 

第三行一个01串,表示从左到右每列上边的N个值。

 

 

下一行一个正整数k,表示按钮的数量。1kN*N

 

 

接下来k行,每行三个整数abc,表示第a行第b列处有一个数值为c的按钮。左上角的格子为第一行第一列。1aN1bN-100C100。不会有同一个地方出现两个按钮。

 

 

 

Output

 

 

 

【输出】

 

 

输出文件名为mima.out

 

 

输出一行,包含一个整数,表示所能取得的最大积分。如果不能使得每列上面的值和每行左边的值一一对应相等,输出“I am stupid!”。

 

 

 

Sample Input

 

6

 

110111

 

101010

 

7

 

5 2 1

 

3 3 -1

 

1 4 2

 

3 5 -2

 

5 4 3

 

5 5 -3

 

6 5 4

 

 

Sample Output

 

6

 

 

 

 

 

 

Data Constraint

 

 

Hint

 

【注释】

 

样例中除图中灰色的按钮以外,全部都按下。共10个测试数据。

 

对于第i个测试数据,N=Max{ 3 , Min{ i , 9 }}

 

题解


        f[i,j,l]=max(f[l?1,x,y]+a[l],f[i,j,k])表示f[i,j]通过选或不选a[l]变成f[x,y]。


代码

 

 type
  arr=record
  x,y,w:longint;
end;
var
  n,m,nm,l:longint;
  sum:int64;
  f:array[0..1000,0..1000,0..1] of longint;
  a:array[0..1000] of arr;
function max(x,y:longint):longint;
begin
  if x>y then exit(x)
  else exit(y);
end;
procedure init;
var
  i,j,x,y,z:longint;
begin
  readln(n);
  nm:=1 shl n-1;
  readln(z);
  x:=0;y:=0;
  for i:=n downto 1 do
    begin
      x:=x+z mod 10 shl (i-1);
      z:=z div 10;
    end;
  readln(z);
  for i:=n downto 1 do
    begin
      y:=y+z mod 10 shl (i-1);
      z:=z div 10;
    end;
  for i:=0 to nm do
    for j:=0 to nm do
      f[i,j,0]:=-maxlongint div 5;
  f[x,y,0]:=0;
  readln(m);
  for i:=1 to m do
    with a[i] do
      readln(x,y,w);
end;
procedure main;
var
  i,j,k,v,u:longint;
begin
  for k:=1 to m do
    begin
      l:=l xor 1;
      for i:=0 to nm do
        for j:=0 to nm do
          with a[k] do
            begin
              u:=i xor 1 shl (x-1);
              v:=j xor 1 shl (y-1);
              f[i,j,l]:=max(f[i,j,l xor 1],f[u,v,l xor 1]+w);
            end;
    end;
end;
var
  i:longint;
begin
  init;
  main;
   sum:=-maxlongint div 5;
  for i:=0 to nm do
    sum:=max(sum,f[i,i,l]);
  if sum>=-100 then write(sum)
    else write('I am stupid!');
end.

  相关解决方案