输入包括两行: 第一行为整数n(1 ≤ n ≤ 50) 第二行为n个整数length[i](1024 ≤ length[i] ≤ 4194304),表示每个任务的长度为length[i]kb,每个数均为1024的倍数。
输出一个整数,表示最少需要处理的时间
5 3072 3072 7168 3072 1024
9216
import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); while (sc.hasNext()) { int n = sc.nextInt(); int[] arr = new int[n]; int sum = 0; for (int i = 0; i < arr.length; i ++) { arr[i] = sc.nextInt() >> 10; sum += arr[i]; } // dp[j]表示在容量为j的情况下可存放的重量 // 如果不放arr[i]重量为dp[j],如果放arr[i]重量为dp[j-arr[i]]+arr[i]; int[] dp = new int[sum / 2 + 1]; for (int i = 0; i < n; i ++) { for (int j = sum / 2; j >= arr[i]; j --) { dp[j] = Math.max(dp[j], dp[j - arr[i]] + arr[i]); } } System.out.println(Math.max(dp[sum / 2], sum - dp[sum / 2]) << 10); } } }
# include <iostream>
# include <vector>
using namespace std;
const int mul=1024;
int main()
{
int n=0,total_len=0;
cin>>n;
vector<int> vi(n,0);
for(int i=0;i<n;i++) {
cin>>vi[i];
vi[i]/=mul;
total_len+=vi[i];
}
int dp_len=total_len/2;
vector<int> dp(dp_len+1,0);
for(int i=0;i<n;i++) {
for(int j=dp_len;j>=vi[i];j--) {
dp[j]=max(dp[j],dp[j-vi[i]]+vi[i]);
}
}
int ret=(total_len-dp[dp_len])*mul;
cout<<ret;
return 0;
}
import sys if __name__ == '__main__': line = sys.stdin.readline() n = int(line) nums = [int(t)//1024 for t in sys.stdin.readline().split()] allnum = sum(nums) half = allnum//2 values = [0]*(half+1) for num in nums: for i in range(half, -1, -1): if i >= num: values[i] = max(values[i], values[i-num]+num) print((allnum-values[-1])*1024)
package go.jacob.day912; import java.util.Scanner; public class Demo1 { public static void main(String[] args) { Scanner sc = new Scanner(System.in); int n = sc.nextInt(); int[] arr = new int[n]; int sum = 0; for (int i = 0; i < n; i++) { arr[i] = sc.nextInt() >> 10; sum += arr[i]; } int[][] res = new int[n + 1][sum / 2 + 1]; for (int i = 0; i < n; i++) { for(int j=sum/2;j>=0;j--){ if(j>=arr[i]){ res[i+1][j]=Math.max(res[i][j], res[i][j-arr[i]]+arr[i]); }else{//else条件必须有 res[i+1][j]=res[i][j]; } } /*for (int j = 0; j < sum / 2; j++) { if (j + 1 >= arr[i]) { res[i + 1][j + 1] = Math.max(res[i][j + 1], res[i][j + 1 - arr[i]] + arr[i]); } }*/ } System.out.println(Math.max(res[n][sum / 2], sum - res[n][sum / 2]) << 10); sc.close(); } }
import java.util.Arrays; import java.util.Collections; import java.util.Scanner; /** * Created by YiBuLZ on 2017/4/7 0007. */ public class Main { public static void main(String[] args) { //以下处理输入 Scanner sc = new Scanner(System.in); int n = sc.nextInt(); Integer[] arr = new Integer[n]; for (int i = 0; i < n; i ++) { arr[i] = sc.nextInt(); } sc.close(); //处理输入ok //先对数组 排序 从大到小排序,为了使这个方法能用,将 //Integer[] arr = new Integer[n]; 如果是int,会报错 Arrays.sort(arr, Collections.reverseOrder()); if (n <= 0) { return; } if (n == 1) { System.out.println(arr[0]); return; } if (n >= 2) { int cpu1 = arr[0]; int cpu2 = arr[1]; for (int i = 2; i < n; i ++) { if (cpu1 > cpu2) { cpu2 += arr[i]; } else { cpu1 += arr[i]; } } System.out.println(Math.max(cpu1, cpu2)); } } }
#include <iostream>#include <algorithm>using namespace std;int main(){int n;cin >> n;int *length = new int [n];int curData, sum = 0, half = 0;for (int i = 0; i < n; i++) {cin >> curData;length[i] = curData / 1024;sum = sum + length[i];}half = sum / 2;sort(length, length + n);// 构建二维数组int **a = new int *[n];for (int i = 0; i < n; i++) {a[i] = new int [half];}// 填写二维数组for (int i = 0; i < half; i++) {for (int j = n -1; j >= 0; j--) {// 最后一行if (j == n-1 ) {if (i+1 >= length[j]) {a[j][i] = length[j];}} else {if ( i+1 >= length[j] ) {a[j][i] = max(a[j+1][i],(length[j] + a[j+1][i-length[j]]));} else {a[j][i] = a[j+1][i];}}}}cout << (sum - a[0][half - 1]) * 1024;return 0;}
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
int main(int argc, const char * argv[]) {
int n;
cin >> n;
int w[n], C = 0, sum = 0;
for (int i = 0; i < n; i++) {
long temp;
cin >> temp;
w[i] = (int)(temp / 1024);
sum += w[i];
}
C = sum / 2;
int f[C + 1];
memset(f, 0, sizeof(f));
for (int i = 0; i < n; i++) {
for (int j = C; j >= w[i]; j--) {
f[j] = max(f[j], f[j - w[i]] + w[i]);
}
}
cout << 1024 * (sum - f[C]);
return 0;
}
#include
using namespace std;
int main() {//01背包
int n=0;
while (scanf("%d",&n)!=EOF) {//输入一个数字n
int w[50]={0};
int total = 0;
int res =0;
for(int i =0 ;i<n;i++){//输入一个数组w
cin>>w[i];
w[i]/=1024;
total+=w[i];//!!
}
total /=2;//最大价值,双核分两组,绝对值差越小越好,时间小的那组越接近于sum/2
int d[n][total];//d[i][j] 背包容量为j,前i个数的最大和
for(int i=0;i<n;i++){
for (int j=0 ; j<total; j++) {
if( (i==0)||(j==0)){
d[i][j]=0;
}else if (j< w[i]){
d[i][j] = d[i-1][j];
}else{
d[i][j]= max(d[i-1][j],d[i-1][j-w[i]]+w[i]);
}
}
}
res = d[n-1][total-1];
res = (total*2-res)*1024;
cout<<res<<endl;
}
return 0;
}
//C++就是简单的一个背包问题,背包总量为sum/2,最终结果就是求sum - dp[sum / 2], dp[sum / 2]
的最大值 #include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
int main(void)
{
int num;
while (cin >> num)
{
vector<int> vec1;
int numsingle,sum=0;
for (int i = 0; i < num; i++)
{
cin >> numsingle;
vec1.push_back(numsingle/1024);
sum += numsingle / 1024;
}
int *dp = new int[sum / 2 + 1]{0};
for (int i = 0; i < num; i++)
{
for (int j = sum / 2; j >= vec1[i]; j--)
{
dp[j] = max(dp[j], dp[j - vec1[i]] + vec1[i]);
}
}
cout << max(sum - dp[sum / 2], dp[sum / 2])*1024 << endl;
}
system("pause");
return 0;
}
python 也是同样做法,但是却超时了,不明所以 import sys if __name__ == '__main__': line=sys.stdin.readline() n=int(line) nums=[int(t)//1024 for t in sys.stdin.readline().split()] allnum=sum(nums) half=allnum//2 values=[0]*(half+1) for num in nums : for i in range(half,num-1,-1): values[i]=max(values[i],values[i-num]+num) print(max(values[half]*1024,(allnum - values[half])*1024))
#include<iostream> #include<vector> #include <algorithm> using namespace std; int dp(vector<int> lengths,int half){ int row = lengths.size(); int col = half; vector<vector<int>> res(row+1,vector<int>(col+1,0)); for(int i=1;i<=row;i++) for(int j=1;j<=col;j++){ if(j>=lengths[i-1]) res[i][j] = max((res[i-1][j-lengths[i-1]]+lengths[i-1]),res[i-1][j]); else res[i][j] = res[i-1][j]; } return res[row][col]; } int main(){ int n; vector<int> lengths; //lengths.push_back(0); cin>>n; int sum = 0; for(int i=0;i<n;i++){ int num; cin>>num; lengths.push_back(num/1024); sum += num/1024; } int half = sum/2; //转化成0-1背包问题 cout<<(sum-dp(lengths,half))*1024<<endl; }
N = int(raw_input()) length = map(lambda x: int(x)//1024, raw_input().split()) V = sum(length) // 2 f = [0] * (V + 1) for i in range(N): v = V while v >= length[i]: f[v] = max(f[v-length[i]] + length[i], f[v]) v = v - 1 print max(f[V], sum(length) - f[V]) * 1024
强烈建议每一种语言有自己的时间时限。Python这个已经不知道还能怎么再优化了。 目前能通过40%。 希望能有人能给出更精简的code
public class Main {
public static int getMax(int[] packTime, int n, int maxTime){
//bestTime[i][j]表示最大时间下的完成第i个任务所需的时间int[][] bestTime = new int[n+1][maxTime+1];for(int j = 0; j <= maxTime; j++ ){
//能容纳最大时间为j
for(int i = 0; i <= n; i++){
//当完成0个任务或者最大时间为0时,时间为0
if(i == 0 || j == 0) {
bestTime[i][j] = 0;
}
//当容纳最大时间小于单独完成第i件任务时间,则为前n-1完成任务时间总和
else if(j < packTime[i-1]){
bestTime[i][j] = bestTime[i-1][j];
}
//完成第i件任务时,两种情况:取最大值
//1.超过容纳最大时间,则为bestTime[i-1][j];
//2.没超过,则为bestTime[i-1][j-packTime[i-1]]+packTime[i-1])
//上述表示为在完成第i件任务时所需时间为bestTime[i-1][j-packTime[i-1]],然后在加上第i个任务时间为packTime[i-1]
else{bestTime[i][j] = Math.max(bestTime[i-1][j], bestTime[i-1][j-packTime[i-1]]+packTime[i-1]);}
}
}
return bestTime[n][maxTime];
}
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int[] packTime = new int[n];
int sum = 0;
for(int i = 0; i < n; i++){
packTime[i] = sc.nextInt()/1024;
sum += packTime[i];
}
int half = sum/2;
int res = getMax(packTime, n, half);
System.out.println(Math.max(res, sum-res)*1024);
}
}
def main(): n = int(input()) lst = list(map(lambda x: int(x) >> 10, input().split())) s = sum(lst) // 2 dp = [0] * (s + 1) for i in range(n): for j in range(s, -1, -1): if j >= lst[i]: tmp = dp[j - lst[i]] + lst[i] if dp[j] < tmp: dp[j] = tmp else: break print(max(dp[s], sum(lst) - dp[s]) << 10) if __name__ == '__main__': main()
#include<iostream> #include<vector> using namespace std; int main() { int n; int sum = 0; cin >> n; vector<int> f(n); for(int i=0;i<n;i++){ cin >> f[i]; f[i] /=1024; sum += f[i]; } vector<vector<int>> dp(n+1,vector<int>(sum/2,0)); for(int i = 1;i<=n;i++) { for(int j=1;j<=sum/2;j++) { dp[i][j] = dp[i-1][j]; if(f[i-1]<=j) dp[i][j] = max(dp[i][j],dp[i-1][j-f[i-1]]+f[i-1]); } } cout << (sum-dp[n][sum/2])*1024; }
n=int(raw_input()) s=list(map(int,raw_input().strip().split())) h=set(s) for i in s: for j in list(h): h.add(i+j) h=[i for i in h if i>=sum(s)//2] print(min(h)) 动态规划 n=int(raw_input()) l=[int(i)/1024 for i in raw_input().strip().split()] sumNum=sum(l) m=sumNum//2 dp=[[0]*(m+1) for i in range(n+1)] for i in range(1,n+1): for j in range(1,m+1): if j<l[i-1]: dp[i][j]=dp[i-1][j] else: dp[i][j]=max(dp[i-1][j],dp[i-1][j-l[i-1]]+l[i-1]) print((sumNum-dp[n][m])*1024) 您的代码已保存 内存超限:您的程序使用了超过限制的内存 case通过率为50.00%
import java.util.Scanner;
/*
* 参考大神的解题思路:https://www.nowcoder.com/questionTerminal/9ba85699e2824bc29166c92561da77fa?orderByHotValue=1&difficulty=11110&page=1&onlyReference=false
*
* 尽可能使两个cpu执行的任务总和相差最小,能够想到转换成容量为sum/2的背包问题也是牛逼了;
* 设置sum/2大小的背包,然后针对所欲的货物大小更新所能够容纳的最大容量
* */
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
while (scanner.hasNext()) {
int n = scanner.nextInt();
int[] nums = new int[n];
int sum = 0;
for (int i = 0; i < n; i++) {
// 缩小容量空间
nums[i] = scanner.nextInt() >> 10;
sum += nums[i];
}
int[] dp = new int[sum / 2 + 1];
for (int i = 0; i < n; i++) {
for (int j = sum / 2; j >= nums[i]; j--) {
// 对每件货物,更新能够获取的最大值
dp[j] = Math.max(dp[j], dp[j - nums[i]] + nums[i]);
}
}
int tmp = dp[sum / 2];
System.out.println((tmp > sum - tmp ? tmp : sum - tmp) << 10);
}
}
}
添加笔记