日期:2014-05-20  浏览次数:21154 次

【oj每周推荐】找出最小值
输入:输入一组正整数(可重复),用空格隔开
输出:把输入的整数分成两组,将这两组数的和相减,得出的最小值即为结果
样例:输入:5 13 27 8 14 输出:3
可以这样分:第一组5+27=32 第二组:8+13+14=35,35-32=3
也可以这样分:第一组8+27=35 第二组:5+13+14=32 ,35-32=3
不管怎样分,求出这个最小值即可

------解决方案--------------------
先退化:
如:8 8 9 9 3 3 1 3 4 5 6
退化成1 3 4 5 6
之后,再行比较这个数据的极小值

退化完成之后的算法示例:
C# code

public int FindMin(string OriginalInput)
{
    string[] ArrayInput = OriginalInput.Split(new string[]{" "}, StringSplitOptions.RemoveEmptyEntries);
    // TODO:......
    // 退化算法开始排除里面成对的重复值.
    int SumArr1 = 0, SumArr2 = 0;
    foreach(int nextInt in arrResult)
    {
        // arrResult 是退化后的整数数组
         if(SumArr1 > SumArr2)
            SumArr2 += nextInt;
        else
            SumArr1 += nextInt;
    }
    return Math.Abs(SumArr1 - SumArr2);
}

------解决方案--------------------
补充:退化算法可以分两步,也可以一步做完
两步:
1.先使用经典的排序算法,将数组排序
2.按顺序遍历数组,当n与n+1相等时,则剔除,当然,这里步长为 +2,只做奇数或偶数的遍历,数据多的时候时间可以省下不少.
一步:
1. 如果使用冒泡这种排序方法.则,在排序的时候,即可剔除相同的两个数据. 需要两个临时变量,一个存放当前值,一个存放上一个值(上一个值一定是没有重复的)

退化完毕之后,可以使用上述方法来操作数据进行相关的求差.

_________________________________________________________

先抛砖,其他兄弟尽管砸~
------解决方案--------------------
探讨
需不需要先排序输入的数字,然后从大往小了加

------解决方案--------------------
探讨
先退化: 
如:8 8 9 9 3 3 1 3 4 5 6 
退化成1 3 4 5 6 

// 退化算法开始排除里面成对的重复值.

------解决方案--------------------
这是我用动态规划解决该问题的代码
程序的输入输出有待优化,先贴出来给大家看下,优化后再发一份


public class Acm1005 
{
Acm1005(){}
public void Kitbag(){}
public int KnapSack(int v[],int w[],int c,int n,int m[][])
{
/*****初始化********/
int jMax=min(w[n]-1,c);//
for (int j=0;j<=jMax;j++)/*m(n,j)=0 0=<j<w[n]*/
{m[n][j]=0;}//在m矩阵最后一行,比jmax小的单位放不下
for (int j=w[n];j<=c;j++)/*m(n,j)=v[n] j>=w[n]*/
{m[n][j]=v[n];}//比jmax大的单位能将第n个物品放下

/*****将剩下的n-1个物品放进去*****/
for (int i=n-1;i>1;i--)
{
jMax=min(w[i]-1,c);//选择第i个物品
for (int j=0;j<=jMax;j++)/*m(i,j)=m(i+1,j) 0=<j<w[i]*/
{m[i][j]=m[i+1][j];}//在放不进第i个物品的位置保留,记录原来的情况
for (int j=w[i];j<=c;j++)/*m(n,j)=v[n] j>=w[n]*/
{m[i][j]=max(m[i+1][j],m[i+1][j-w[i]]+v[i]);}
//在能放进第i个物品的位置,有选择性的确定是替换还是不替换,并记录
m[1][c]=m[2][c];
if(c>=w[1])
{m[1][c]=max(m[1][c],m[2][c-w[1]]+v[1]);}
}
for(int i=1;i<6;i++)
{
for(int j=0;j<11;j++)
{
System.out.print(m[i][j]+" ");
}
System.out.print("\n");
}

int j=0;
return m[1][10];
}
public int max(int a,int b)
{
if(a>=b){return a;}
else{return b;}

}
public int min(int a,int b)
{
if(a>=b){return b;}
else{return a;}
}
public static void main(String[] args)
{
Acm1005 acm1005=new Acm1005(); 
int[] w={0,2,2,6,5,4};// 石头的重量,由于个人习惯,数组的0位置不放
int[] v={0,2,2,6,5,4};//每一个石头的值为1
int halfWeight=10;
int[][] m=new int[6][halfWeight+1];
//m(i,j)是背包容量为j,可选择物品为i,i+1,…,n时0-1背包问题的最优值
System.out.print("最小值为:"+(19-2*acm1005.KnapSack(v,w,10,5,m)));

}

}
------解决方案--------------------
程序如下:

用.net 3.5编写,大量用到LINQ,楼主用.net 3.5创建一个C# Console Application Project,然后将我的程序Copy + Peste即可

给分

using System;