111,130
社区成员
发帖
与我相关
我的任务
分享
function sand($ary){
$size = sizeof($ary);
$order_ary = Array();
$end_ary = Array();
for($i = 0;$i < $size-1 ;$i ++){
//将$order_ary初始化为array(0,0,...);
$order_ary[$i] = 0;
$end_ary[$i] = $size - $i- 2;
}
$not_finish = true;
$counter_begin = 0;
$min_result = 0;
$min_array = Array();
while ($not_finish){
$total_times = 0;
$result = 0;
$ary_new = $ary;
while ($total_times < $size-1){
$local_result = $ary_new[($order_ary[$total_times])] + $ary_new[($order_ary[$total_times])+1];
$result += $local_result;
for($i = 0 ;$i< sizeof($ary_new); $i ++) {
if ($i == ($order_ary[$total_times])) {
$ary_new[$i] = $local_result;
} else if($i > ($order_ary[$total_times])){
$ary_new[$i] = $ary_new[$i+1];
}
}
unset($ary_new[sizeof($ary_new)-1]);
$total_times += 1;
}
if ($end_ary == $order_ary || $end_ary == $order_ary) {
$not_finish = false;
}
if ($min_result == 0 || $min_result > $result) {
$min_result = $result;
$min_array = $order_ary;
}
$order_ary = add_one($order_ary);
}
return array($min_result,$min_array);
}
function add_one($order_ary){
//让数组自动添加1
$size = sizeof($order_ary);
for($i = $size-1 ;$i > -1; $i--){
if ($order_ary[$i] + 1 > ($size - $i-1) ) {
$order_ary[$i] = 0;
} else {
$order_ary[$i] = $order_ary[$i] +1;
break;
}
}
return $order_ary;
}
$ary = array(6,5,5,6);
$min_result = sand($ary);
echo 'Limit value:'.($min_result[0]);
echo '<br />Limit method:<br />';
print_r($min_result[1]);
using System;
using System.Linq;
namespace CsdnTest
{
public class TreeNode<T>
{
public T Key;
public int Distance;
public TreeNode<T> Left;
public TreeNode<T> Right;
public TreeNode<T> Parent;
public TreeNode(T key, int dis, TreeNode<T> left, TreeNode<T> right)
{
Key = key; Distance = dis;
Left = left; Right = right;
}
}
public delegate int KeyComparer<T>(T T1, T T2);
public class LeftistTree<T>
{
public TreeNode<T> Root;
public static KeyComparer<T> Comparer;
public static TreeNode<T> Merge(TreeNode<T> node1, TreeNode<T> node2)
{
if (node1 == null)
return node2;
else if (node2 == null)
return node1;
if ((Comparer != null && Comparer(node1.Key, node2.Key) > 0)
|| (node1.Key.GetHashCode().CompareTo(node2.Key.GetHashCode()) > 0 && Comparer == null))
Swap<TreeNode<T>>(ref node1, ref node2);
node1.Right = Merge(node1.Right, node2);
if (node1.Right != null)
node1.Right.Parent = node1;
if (GetDistance(node1.Right) > GetDistance(node1.Left))
Swap<TreeNode<T>>(ref node1.Right, ref node1.Left);
node1.Distance = GetDistance(node1.Right) + 1;
return node1;
}
public static int GetDistance(TreeNode<T> node)
{
return node == null ? -1 : node.Distance;
}
public static void Remove(TreeNode<T> node)
{
TreeNode<T> parent = node.Parent;
TreeNode<T> newNode = Merge(node.Left, node.Right);
if (newNode != null)
newNode.Parent = parent;
if (parent != null)
{
if (parent.Left == node)
parent.Left = newNode;
else
parent.Right = newNode;
}
while (parent != null)
{
if (GetDistance(parent.Left) < GetDistance(parent.Right))
Swap<TreeNode<T>>(ref parent.Left, ref parent.Right);
if (GetDistance(parent.Right) + 1 == parent.Distance)
break;
parent.Distance = GetDistance(parent.Right) + 1;
parent = parent.Parent;
}
}
public static void Swap<U>(ref U node1, ref U node2)
{
U temp = node1;
node1 = node2;
node2 = temp;
}
public T Min
{
get { return Root.Key; }
}
public TreeNode<T> Enqueue(T value)
{
TreeNode<T> node = new TreeNode<T>(value, 0, null, null);
Root = Merge(Root, node);
return node;
}
public TreeNode<T> Dequeue()
{
TreeNode<T> minNode = Root;
Root = Merge(Root.Left, Root.Right);
return minNode;
}
public void RemoveNode(TreeNode<T> node)
{
if (node == Root)
Dequeue();
else
LeftistTree<T>.Remove(node);
}
}
public class PairNode
{
public TreeNode<Stone> Node;
public HPQueue Tree;
public PairNode(TreeNode<Stone> node, HPQueue tree)
{
Node = node;
Tree = tree;
}
}
public class Stone
{
public int Value;
public int Index;
public bool IsLeaf;
public PairNode Left;
public PairNode Right;
public Stone(int value, int index, bool isLeaf)
{
Value = value;
Index = index;
IsLeaf = isLeaf;
}
public static int Compare(Stone item1, Stone item2)
{
if (item1.Value == item2.Value)
return item1.Index - item2.Index;
else
return item1.Value - item2.Value;
}
}
public class HPQueue
{
public LeftistTree<Stone> HPQTree = new LeftistTree<Stone>();
public TreeNode<HPQueue> TreeNode;
public int Index;
public int Left = -1;
public int Right = -1;
public TreeNode<Stone> Min
{
get { return HPQTree.Root; }
}
public TreeNode<Stone> SecMin
{
get
{
if (HPQTree.Root == null || HPQTree.Root.Left == null)
return null;
else if (HPQTree.Root.Right == null)
return HPQTree.Root.Left;
else if (Stone.Compare(HPQTree.Root.Left.Key, HPQTree.Root.Right.Key) > 0)
return HPQTree.Root.Right;
else
return HPQTree.Root.Left;
}
}
public int MinSum = 0;
public void SetMinSum()
{
if(SecMin != null)
MinSum = Min.Key.Value + SecMin.Key.Value;
}
public static int Compare(HPQueue item1, HPQueue item2)
{
if (item1.MinSum == item2.MinSum)
return item1.Index - item2.Index;
else
return item1.MinSum - item2.MinSum;
}
}
class Program
{
static Stone[] Stones;
static HPQueue[] HPQs;
static LeftistTree<HPQueue> MasterTree = new LeftistTree<HPQueue>();
static void InitStones()
{
Random random = new Random(10);
int[] array = Enumerable.Range(1, 100000).Select(t => random.Next(1, 100)).ToArray();
Stones = new Stone[array.Length];
for (int i = 0; i < Stones.Length; i++)
Stones[i] = new Stone(array[i], i, true);
}
static void InitHPQs()
{
LeftistTree<HPQueue>.Comparer = HPQueue.Compare;
LeftistTree<Stone>.Comparer = Stone.Compare;
HPQs = new HPQueue[Stones.Length - 1];
for (int i = 0; i < Stones.Length - 1; i++)
{
HPQueue item = new HPQueue();
Stones[i].Right = new PairNode(item.HPQTree.Enqueue(Stones[i]), item);
Stones[i + 1].Left = new PairNode(item.HPQTree.Enqueue(Stones[i + 1]), item);
item.Left = i;
item.Right = i + 1;
item.Index = i;
item.SetMinSum();
item.TreeNode = MasterTree.Enqueue(item);
HPQs[i] = item;
}
}
static void Main(string[] args)
{
int minCost = 0;
InitStones();
InitHPQs();
for (int i = 0; i < Stones.Length - 1; i++)
{
HPQueue item = MasterTree.Dequeue().Key;
Stone min = item.HPQTree.Dequeue().Key;
Stone secMin = item.HPQTree.Dequeue().Key;
if (min.Index > secMin.Index)
LeftistTree<Stone>.Swap<Stone>(ref min, ref secMin);
Deal(min, item);
Deal(secMin, item);
min.Value += secMin.Value;
Stones[secMin.Index] = null;
minCost += min.Value;
item.HPQTree.Enqueue(min);
item.SetMinSum();
item.TreeNode = MasterTree.Enqueue(item);
}
Console.WriteLine(minCost);
Console.ReadKey();
}
private static void Deal(PairNode pair, HPQueue item)
{
if (pair != null && pair.Tree != item)
{
MasterTree.RemoveNode(pair.Tree.TreeNode);
HPQs[pair.Tree.Index] = null;
pair.Tree.HPQTree.RemoveNode(pair.Node);
item.HPQTree.Root = LeftistTree<Stone>.Merge(item.HPQTree.Root, pair.Tree.HPQTree.Root);
//修改合并后的左右节点
item.Left = Math.Min(item.Left, pair.Tree.Left);
item.Right = Math.Max(item.Right, pair.Tree.Right);
//修改左右节点对应的树
if (Stones[item.Left] != null && Stones[item.Left].Right != null)
Stones[item.Left].Right.Tree = item;
if (Stones[item.Right] != null && Stones[item.Right].Left != null)
Stones[item.Right].Left.Tree = item;
}
}
private static void Deal(Stone stone, HPQueue item)
{
if (stone.IsLeaf)
{
Deal(stone.Left, item);
Deal(stone.Right, item);
stone.Left = null;
stone.Right = null;
stone.IsLeaf = false;
}
}
}
}