Problem:
Problem F: Line Puzzle

プログラミングでパズルを解いてみよう。

n × n の数字が格子状に並んでいる。数字のいくつかは丸で囲まれており、これらを起点と呼ぶことにする。パズルのルールは以下のとおりである：

各起点から縦・横に進む１本の線を引く（斜めには引けない）。

通った数字の和が起点の数字と同じになるように線を伸ばす。

線は枝分かれしてはいけない。

線はすでに引かれた数字を通ることはできない（線は交差してはいけない）。

線は２個以上の起点を通ることはできない。

下図に示すように、パズルのゴールはすべての起点を使い、すべての数字に線を引くことである。

あなたの仕事は、パズルを解くプログラムを作成することである。
ただしこの問題では、与えられたパズルが解けるものかどうかを判定するだけでよい。

Input

入力は複数のデータセットからなる。各データセットの形式は以下のとおりである：

n
n × n の数字

n × n の数字が与えられるパズルを示し、起点の数字は負の数として与えられる。

n が 0 のとき入力の終わりを示す。

n は 3 以上 8 以下、起点以外の数字は 1 以上 50 以下、起点は -50 以上 -1 以下であると仮定してよい。また、入力されるパズルの性質として以下のことを仮定してよい：

与えられるパズルの各行、各列には最低でも１つの起点がある。

起点の個数は、全体の数字の個数 (n × n) の 20 % から 40 % 程度である。

Output

各データセットに対して、パズルが解けるものであれば "YES" を、そうでなければ "NO" と１行に出力せよ。

Sample Input

3
-3 1 1
2 -4 1
2 1 -1
3
-4 1 1
1 1 -6
1 -5 3
4
-8 6 -2 1
2 -7 -2 1
1 -1 1 1
1 1 1 -5
6
2 2 3 -7 3 2
1 -10 1 1 3 2
2 6 5 2 -6 1
3 4 -23 2 2 5
3 3 -6 2 3 7
-7 2 3 2 -5 -13
6
2 2 3 -7 3 2
1 -10 1 1 3 2
2 6 5 2 -6 1
3 4 -23 2 2 5
3 3 -6 2 3 7
-7 2 3 2 -5 -12
0

Output for the Sample Input

YES
NO
NO
YES
NO

Solution in C# (judge verdict: Time Limit Exceeded)

using System;
using System.Collections.Generic;
using System.Text;

class TEST{
	static void Main(){
		while(true){
			var n=int.Parse(Console.ReadLine());
			if(n==0)break;
			Sol mySol=new Sol(n);
			mySol.Solve();
		}
	}
}


class Sol{
	int n;
	int[,] Arr;
	List<Point> L;
	int state;

	public Sol(int n_){
		n=n_;
		L=new List<Point>();
		state=0;
		Arr=new int[n+2,n+2];

		int cnt=0;

		for(int i=0;i<n+2;i++)Arr[0,i]=Arr[n+1,i]=Arr[i,0]=Arr[i,n+1]=0;
		for(int i=0;i<n;i++){
			var d=Console.ReadLine().Split(' ');
			for(int j=0;j<n;j++){
				Arr[i+1,j+1]=int.Parse(d[j]);
				if(Arr[i+1,j+1]<0)L.Add(new Point(i+1,j+1,Arr[i+1,j+1]));
				cnt+=Arr[i+1,j+1];
			}
		}
		if(cnt!=0)state=-99;
	}

	public void Solve(){
		if(state==-99){
			Console.WriteLine("NO");
			return;
		}
		
		//降順でソート（絶対値の小さい順）
		L.Sort((x,y)=>x.V>y.V?-1:(x.V<y.V?1:0));
		
		state=0;//dfsで解けたら１
		
		//dfs: score：手持ちの数。now:挑戦中の起点 r,c:現在地点
		int now=0;
		int score=0;
//dbg.wArr(Arr);		
		dfs(now,score,L[now].R,L[now].C);
		
		if(state==1){
			Console.WriteLine("YES");
			return;
		}
		Console.WriteLine("NO");
	}

	void dfs(int now_,int score_,int r_,int c_){
		int score=score_;
		int now=now_;
		int r=r_;
		int c=c_;
		score+=Arr[r,c];
		int bak=Arr[r,c];
		Arr[r,c]=0;
//Console.WriteLine("score={0},now={1},r={2},c={3},bak={4}",score,now,r,c,bak);
//dbg.wArr(Arr);		
		if(score==0){
			if(now<L.Count-1){
				dfs(now+1,score,L[now+1].R,L[now+1].C);
			}
			if(now==L.Count-1){
				state=1;
			}
			score-=bak;
			Arr[r,c]=bak;
			return;
		}
		
		
		if(Arr[r-1,c]>0 && score+Arr[r-1,c]<=0)dfs(now,score,r-1,c);
		if(Arr[r+1,c]>0 && score+Arr[r+1,c]<=0)dfs(now,score,r+1,c);
		if(Arr[r,c-1]>0 && score+Arr[r,c-1]<=0)dfs(now,score,r,c-1);
		if(Arr[r,c+1]>0 && score+Arr[r,c+1]<=0)dfs(now,score,r,c+1);
		
		score-=bak;
		Arr[r,c]=bak;
		return;
	}
}



class Point{
	public int R{get;set;}
	public int C{get;set;}
	public int V{get;set;}
	public Point(int i,int j,int v){
		this.R=i;
		this.C=j;
		this.V=v;
	}
}
	
class dbg{
	public static void wArr(int[,] A){
		Console.WriteLine("--table--");
		for(int i=0;i<A.GetLength(0);i++){
			for(int j=0;j<A.GetLength(1);j++){
				Console.Write("{0}\t",A[i,j]);
			}
			Console.WriteLine("");
		}
		Console.WriteLine("--table end--");
		Console.WriteLine("");
	}
	public static void w(String S){
		Console.WriteLine(S);
	}
	public static void w(int i){
		Console.WriteLine(i);
	}
}