求好心大佬帮忙看一下代码
  • 板块题目总版
  • 楼主baba666666
  • 当前回复3
  • 已保存回复3
  • 发布时间2025/1/18 08:35
  • 上次更新2025/1/18 11:46:54
查看原帖
求好心大佬帮忙看一下代码
1071380
baba666666楼主2025/1/18 08:35

现在有一个长度为length=m的木头按以下切割的方法 给出n个长度为,len1,len2,len3.....leni<m 使得x1len1+x2len2+x3*len3.....最大并且<=m,其中x1,x2,x3.....xi的数量有可能都不相同

求出x1,x2,x3....xi

并且切割的时候会有损失sq,sq也手动输入。例如切割一段就有sq长度的损失

输入要求:

m n sq

接下来输入n个小余m的整数

len1,len2,len3......lenn

输出一共(n+1)行

x1=?

x2=?

....

xn=?

??(这行为切割后剩余的木头长度)

注: 1、但是要注意的是,例如木头长度length为5,要切割成len1=2,损失为sq=1。只需要切一刀,损失为1,就可以得到两个为2的木材

2、以上数据都为正整数

遇到问题比如一个例子:length=381,sq=3,n=3

len1=66,len2=87,len3=153

最优的应该是(66+3)+(66+3)+(87+3)+153=381 (+3是切割损失的锯缝)
这个是3个锯缝,下面C#代码会算成4个锯缝,求大佬帮忙优化一下代码,或者有好的代码可以给我借鉴借鉴。

public static void mains()
{
    Console.WriteLine("请输入目标长度(例如 1000):");
    int target = int.Parse(Console.ReadLine());

    Console.WriteLine("请输入每次切割的损失长度(sq):");
    int sq = int.Parse(Console.ReadLine());

    Console.WriteLine("请输入长度的数量:");
    int count = int.Parse(Console.ReadLine());

    List<int> lengths = new List<int>();
    for (int i = 0; i < count; i++)
    {
        Console.WriteLine($"请输入第 {i + 1} 个长度(<1000):");
        int length = int.Parse(Console.ReadLine());
        lengths.Add(length);
    }

    var result = FindMaxCombination(lengths, target, sq);

    Console.WriteLine($"最大组合的总长度为:{result.Item1}");
    Console.WriteLine($"剩余的长度为:{result.Item3}");
    Console.WriteLine("对应的系数为:");
    for (int i = 0; i < result.Item2.Length; i++)
    {
        Console.WriteLine($"x{i + 1} = {result.Item2[i]}");
    }
}


static Tuple<int, int[], int> FindMaxCombination(List<int> lengths, int target, int sq = 3)
{
    int[] dp = new int[target + 1];
    int[] lastUsed = new int[target + 1]; // 记录达到每个值最后使用的长度索引
    int[] cutCount = new int[target + 1]; // 记录达到每个值时的切割次数

    for (int i = 0; i < lengths.Count; i++)
    {
        for (int j = lengths[i] + sq; j <= target; j++)
        {
            if (dp[j - (lengths[i] + sq)] + lengths[i] > dp[j])
            {
                dp[j] = dp[j - (lengths[i] + sq)] + lengths[i];
                lastUsed[j] = i;
                cutCount[j] = cutCount[j - (lengths[i] + sq)] + 1;
            }
        }
    }

    // 回溯找到使用的每个长度的次数
    int[] counts = new int[lengths.Count];
    int totalCuts = 0;
    int currentTarget = target;
    while (currentTarget > 0)
    {
        if (lastUsed[currentTarget] == 0 && dp[currentTarget] == 0) break; // 避免无限循环
        int lengthIndex = lastUsed[currentTarget];
        counts[lengthIndex]++;
        totalCuts += cutCount[currentTarget] - cutCount[currentTarget - (lengths[lengthIndex] + sq)];
        currentTarget -= lengths[lengthIndex] + sq;
    }
    int residue = target - (dp[target] + totalCuts * sq);

    return Tuple.Create(dp[target], counts, residue);
}
2025/1/18 08:35
加载中...