输入描述:第一行输入一个正整数n(1<=n<=1000),表示一共有n张贴图。 接下来n行每行有两个正整数w,s(8<=w<=512; w为2的幕次,0<s<100),w表示正方形贴图的边长,s表示贴图的权重,权重越大贴图越重要。 输出描述:假定图集的最终得分为sum (贴图最终面积/贴图原始面积贴图权重)。输出一个数字,表示所有填充方式中,最大的图集得分。 输出结果四舍五入后保留两位小数。 使用Java写出这个算法。
时间: 2023-06-10 12:04:46 浏览: 148
好的,接下来我开始回答你的问题。
首先,为了解决这个问题,我们需要依次读入每张贴图的边长w和权重s,并计算每种填充方式得到的贴图最终面积/贴图原始面积贴图权重的值sum。因为每个正方形贴图可以存在多个填充方式,因此在计算sum的过程中,我们需要找到每张贴图的最大值。
接下来,我们可以使用动态规划来解决这个问题,以便更高效地处理计算贴图面积的过程。我们可以维护一个dp数组,其中dp[i][j]表示填充前i个贴图,总宽度为j时,能达到的最大sum值。我们可以使用以下公式来更新dp[i][j]的值:
dp[i][j] = max(dp[i-1][j-w]+s*w*w/j*j , dp[i][j]);其中w和s表示读入的贴图的w和s,j-w表示之前填充完贴图后剩余的宽度,s*w*w/j*j表示当前贴图的贴图最终面积/贴图原始面积贴图权重的值sum。
最后,我们在dp数组的最后一行中找到最大值,并将其保留两位小数后输出即可。
下面是该算法的Java代码实现:
import java.math.BigDecimal;
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int W = 512;
double[][] dp = new double[n + 1][W + 1];
for (int i = 1; i <= n; i++) {
int w = sc.nextInt();
int s = sc.nextInt();
double sum = 1.0 * s * w * w / (W * W);
for (int j = w; j <= W; j++) {
dp[i][j] = Math.max(dp[i][j], dp[i][j - w] + sum);
dp[i][j] = Math.max(dp[i][j], dp[i - 1][j]);
}
}
System.out.println(new BigDecimal(dp[n][W]).setScale(2, BigDecimal.ROUND_HALF_UP));
}
}
希望能够帮到你解决问题,如有不懂之处,欢迎继续询问!
阅读全文