小v是公司的运维工程师,现有一个有关应用程序部署的任务如下:
1、一台服务器的磁盘空间、内存是固定的,现在有N个应用程序要部署;2、每个应用程序所需要的磁盘、内存不同,每个应用程序允许访问的用户数也不同,且同一个应用程序不能在一台服务器上部署多个。
对于一台服务器而言,如何组合部署应用程序能够使得单台服务器允许访问的用户数最多?
1、一台服务器的磁盘空间、内存是固定的,现在有N个应用程序要部署;2、每个应用程序所需要的磁盘、内存不同,每个应用程序允许访问的用户数也不同,且同一个应用程序不能在一台服务器上部署多个。
输入包括三个参数,空格分隔,分别表示服务器的磁盘大小、内存大小,以及应用程序列表;
其中第三个参数即应用程序列表,表述方式为:多个应用程序信息之间用 '#' 分隔,每个应用程序的信息包括 ',' 分隔的部署所需磁盘空间、内存、允许访问的用户量三个数字;比如 50,20,2000 表示部署该应用程序需要50G磁盘空间,20G内存,允许访问的用户数是2000
单台服务器能承载的最大用户数
15 10 5,1,1000#2,3,3000#5,2,15000#10,4,16000
31000
组合部署服务5,2,15000、10,4,16000 ,可以让单台服务器承载最大用户数31000
/* 背包问题,递归求解 */ #include <iostream> #include <cstdio> #include <cstdlib> //#include <map> using namespace std; /* * Welcome to vivo ! */ int getCountOfApp(const char* input){ if(NULL == input){ return 0; } int cnt = 0; for(int i=0;input[i]!=0;++i){ if(input[i] == ','){ ++cnt; } } return cnt/2; } //id start from 0 int getPositionOfApp(const char* input, const int id){ int cntOfComma = id*2 + 1; int i=0; for(;input[i]!=0&&cntOfComma!=0;++i){ if(input[i] == ','){ --cntOfComma; } } while(input[--i]!=' '&&input[i]!='#'); return i+1; } #define APP_MAX 1000 #define DP_MAX 2048 int disks[APP_MAX]; int mems[APP_MAX]; int users[APP_MAX]; int dp[DP_MAX*DP_MAX]; int solve_res(int disks[],int mems[],int users[],int N,int DISK,int MEM,int index){ if(index<0 || DISK <= 0 || MEM <= 0){ return 0; } int res = solve_res(disks,mems,users,N,DISK,MEM,index-1); if (disks[index] <= DISK && mems[index] <= MEM) { res = res>(users[index] + solve_res(disks,mems,users,N,DISK-disks[index],MEM-mems[index],index-1))? res:(users[index] + solve_res(disks,mems,users,N,DISK-disks[index],MEM-mems[index],index-1)); } return res; } int solution(const char* input){ const int countOfApp = getCountOfApp(input); if(0 == countOfApp){ return 0; } int res = 0; int disk = 0; int mem = 0; sscanf(input, "%d %d", &disk, &mem); for(int i=0; i< countOfApp;++i){ const int pos = getPositionOfApp(input, i); sscanf(input+pos, "%d,%d,%d", &disks[i], &mems[i], &users[i]); } res = solve_res(disks,mems,users,countOfApp,disk,mem,countOfApp-1); // TODO Write your code here! return res; } int main(int argc, char* args[]) { char input[10000]; cin.getline(input,10000); cout<<solution(input)<<endl; }
#回溯 while True: try: string = input().split(" ") m, n = int(string[0]), int(string[1]) apps = [[int(y) for y in x.split(",")] for x in string[-1].split("(1569)#")] res = [] def backtrack(apps,m,n,users): if m<0&nbs***bsp;n<0: return elif apps==[]: res.append(users) return else: for i in range(len(apps)): if m-apps[i][0]<0&nbs***bsp;n-apps[i][1]<0: res.append(users) backtrack(apps[:i]+apps[i+1:],m-apps[i][0],n-apps[i][1],users+apps[i][2]) backtrack(apps,m,n,0) print(max(res)) except: break
//write code here vector<vector<vector<int>>> dp(countOfApp + 1,vector<vector<int>>(disk+1,vector<int>(mem+1))); for(int i = 1; i <= countOfApp; i++){ for(int j = disk; j > 0; j--){ for(int k = mem; k > 0; k--){ if(j >= disks[i-1] && k >= mems[i-1]){ dp[i][j][k] = max(dp[i - 1][j][k],dp[i - 1][j - disks[i-1]][k - mems[i-1]]+ users[i-1]); }else{ dp[i][j][k] = dp[i - 1][j][k]; } } } } return dp[countOfApp][disk][mem];
import java.io.*; import java.util.*; /** * Welcome to vivo ! */ public class Main { public static void main(String[] args) throws Exception { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); String inputStr = br.readLine(); String[] input = inputStr.split(" "); int totalDisk = Integer.parseInt(input[0]); int totalMemory = Integer.parseInt(input[1]); List<Service> services = parseServices(input[2].split("#")); int output = solution(totalDisk, totalMemory, services); System.out.println(output); } private static int solution(int totalDisk, int totalMemory, List<Service> services) { // TODO Write your code here int len = services.size(); int[][][] dp = new int[len + 1][totalDisk + 1][totalMemory + 1]; for(int i = 1; i <= len; i++) for(int j = totalDisk; j > 0; j--) for(int k = totalMemory; k > 0; k--){ if(j >= services.get(i - 1).getDisk() && k >= services.get(i - 1).getMemory()){ dp[i][j][k] = Math.max(dp[i - 1][j][k], dp[i - 1][j - services.get(i - 1).getDisk()][k - services.get(i - 1).getMemory()] + services.get(i - 1).getusers()); }else{ dp[i][j][k] = dp[i - 1][j][k]; } } return dp[len][totalDisk][totalMemory]; } private static List<Service> parseServices(String[] strArr) { if (strArr == null || strArr.length == 0) { return new ArrayList<Service>(0); } List<Service> services = new ArrayList<>(strArr.length); for (int i = 0; i < strArr.length; i++) { String[] serviceArr = strArr[i].split(","); int disk = Integer.parseInt(serviceArr[0]); int memory = Integer.parseInt(serviceArr[1]); int users = Integer.parseInt(serviceArr[2]); services.add(new Service(disk, memory, users)); } return services; } static class Service { private int disk; private int memory; private int users; public Service(int disk, int memory, int users) { this.disk = disk; this.memory = memory; this.users = users; } public int getDisk() { return disk; } public void setDisk(int disk) { this.disk = disk; } public int getMemory() { return memory; } public void setMemory(int memory) { this.memory = memory; } public int getusers() { return users; } public void setusers(int users) { this.users = users; } } }
private static int solution(int totalDisk, int totalMemory, List<Service> services) { // TODO Write your code here // 三维背包问题 int n = services.size(); int[][][] dp = new int[n + 1][totalDisk + 1][totalMemory + 1]; for(int i = 1; i <= n; i++){ for(int j = totalDisk; j > 0; j--){ for(int k = totalMemory; k > 0; k--){ if(j >= services.get(i - 1).getDisk() && k >= services.get(i - 1).getMemory()){ // 磁盘空间和内存还够,选择第i个应用程序或不选择第i个应用程序 dp[i][j][k] = Math.max(dp[i - 1][j][k], dp[i - 1][j - services.get(i - 1).getDisk()][k - services.get(i - 1).getMemory()] + services.get(i - 1).getusers()); }else{ // 磁盘空间不够 dp[i][j][k] = dp[i - 1][j][k]; } } } } return dp[n][totalDisk][totalMemory]; }
def solution(total_disk,total_memory,app_list): # 不用背包法 app_list = sorted(app_list, key=lambda x:x[2], reverse=True) # 按照用户人数降序排列 disk = 0 memory = 0 num = 0 for i in app_list: if disk + i[0] <= total_disk and memory + i[1]<= total_memory: # 从前往后一个一个加,所取的值总是最大的 num += i[2] disk += i[0] memory += i[1] return num if __name__ == "__main__": input1 = input() disk = int(input1.split()[0]) memory = int(input1.split()[1]) input2 = input1.split()[2] app_list = [[int(j) for j in i.split(',')] for i in input2.split('#')] print(solution(disk,memory,app_list))
input1 = input() A = int(input1.split()[0]) B = int(input1.split()[1]) input2 = input1.split()[2] app_list = [[int(j) for j in i.split(',')] for i in input2.split('#')] dp = [[0 for _ in range(B+1)] for _ in range(A+1)] for a,b,c in app_list: for j in range(A, a - 1, -1): for k in range(B, b - 1, -1): dp[j][k] = max(dp[j][k], dp[j - a][k - b] + c) print(dp[-1][-1])我比我这个简单的吗?直接将三维dp变成二维dp。背包九讲
#include "stdio.h" #include <stdlib.h> #include "string.h" /* * Welcome to vivo ! */ int make (int *a,int b) { int i,j=0; int c; for (i=0;i<b;i++) { if (a[i]!=-1) { c=a[i]; j=i; break; } } for (i=0;i<b;i++) { if (c>a[i] && a[i]>0) { c=a[i]; j=i; } } return j; } int solution(int countOfApp, int disk, int mem){ int i; int Disk=0,Mem=0,User=0; for (i=0;i<countOfApp;i++) { if (disks[i]<=disk && mems[i]<=mem) { Disk=Disk+disks[i]; Mem =Mem+mems[i]; User=User+users[i]; } } for (i=0;i<countOfApp;i++) { if (Disk<=disk && Mem<=mem) return User; else { int min= make(users,countOfApp); Disk=Disk-disks[min]; Mem=Mem-mems[min]; User=User-users[min]; users[min]=-1; } } }
//动态规划解决背包问题 private static int solution4(int totalDisk, int totalMemory, List<Service> services) { // TODO Write your code here int len=services.size(); int[][][] maxValue=new int[len+1][totalDisk+1][totalMemory+1]; for(int i=1;i<=len;i++) for(int d=1;d<=totalDisk;d++) for(int m=1;m<=totalMemory;m++){ if(services.get(i-1).getDisk()<=d&&services.get(i-1).getMemory()<=m){ //能放,存在放不放的问题;因为如果当前容量很大一定是放的,但是如果不是很大(假如只能存放前一个或者当前这个),可能放前一个比当前的价值更大 maxValue[i][d][m]=Math.max(maxValue[i-1][d][m], maxValue[i-1][d-services.get(i-1).getDisk()][m-services.get(i-1).getMemory()]+services.get(i-1).getusers()); }else{ maxValue[i][d][m]=maxValue[i-1][d][m]; } } return maxValue[len][totalDisk][totalMemory]; }
// 磁盘+内存尽量饱和的情况下,最大的用户数 // 玩了一手前缀和竟然过了 private static int solution(int totalDisk, int totalMemory, List<Service> services) { int n = services.size(); int[][] pre = new int[n+1][3]; for (int i = 0; i < n; i++) { pre[i+1][0] = pre[i][0] + services.get(i).disk; pre[i+1][1] = pre[i][1] + services.get(i).memory; pre[i+1][2] = pre[i][2] + services.get(i).users; } int max = 0; for (int i = 1; i <= n; i++) { for (int j = 0; j < i; j++) { if (pre[i][0] - pre[j][0] <= totalDisk && pre[i][1]-pre[j][1] <= totalMemory) { max = Math.max(max, pre[i][2]-pre[j][2]); } } } return max; }
import java.io.*; import java.util.*; public class Main { public static void main(String[] args) throws Exception { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); String inputStr = br.readLine(); String[] input = inputStr.split(" "); int totalDisk = Integer.parseInt(input[0]); int totalMemory = Integer.parseInt(input[1]); List<Service> services = parseServices(input[2].split("#")); int output = solution(totalDisk, totalMemory, services); System.out.println(output); } // ------------------------------------------------------------------------------------- private static int solution(int totalDisk, int totalMemory, List<Service> services) { Collections.sort(services, new Comparator<Service>(){ // 按照用户数,从大到小排序 @Override public int compare(Service s1, Service s2) { if(s2.users > s1.users) { return 1; } return -1; } }); int sum = 0; // 单台服务器能承载的最大用户数 for(Service it : services){ // 从用户数最大的应用程序开始遍历 if(totalDisk>=it.disk && totalMemory>=it.memory){ // 同时满足所需磁盘空间和内存时 sum += it.users; // 累计用户数 totalDisk -= it.disk; totalMemory -= it.memory; } } return sum; } // ------------------------------------------------------------------------------------- private static List<Service> parseServices(String[] strArr) { if (strArr == null || strArr.length == 0) { return new ArrayList<Service>(0); } List<Service> services = new ArrayList<>(strArr.length); for (int i = 0; i < strArr.length; i++) { String[] serviceArr = strArr[i].split(","); int disk = Integer.parseInt(serviceArr[0]); int memory = Integer.parseInt(serviceArr[1]); int users = Integer.parseInt(serviceArr[2]); services.add(new Service(disk, memory, users)); } return services; } static class Service { private int disk; private int memory; private int users; public Service(int disk, int memory, int users) { this.disk = disk; this.memory = memory; this.users = users; } public int getDisk() { return disk; } public void setDisk(int disk) { this.disk = disk; } public int getMemory() { return memory; } public void setMemory(int memory) { this.memory = memory; } public int getusers() { return users; } public void setusers(int users) { this.users = users; } } }
for(int i = 0; i < countOfApp; i++){ for(int j = disk; j >= disks[i]; j--) for(int k = mem; k >= mems[i]; k--){ dp[j][k] = max(dp[j][k],dp[j-disks[i]][k-mems[i]]+users[i]); } } return dp[disk][mem];
function solution(disk, mem, apps) { // TODO Write your code here let a=disk let b=mem var grid=[] let temp=apps for(let i=0;i<temp.length;i++){ let item=temp[i].split(',').map(Number) grid.push(item) } let dp=[] for(let i=0;i<=a;i++){ dp[i]=[] for(let j=0;j<=b;j++){ dp[i][j]=0 } } let N=grid.length for(let k=0;k<N;k++){ for(let i=a;i>=grid[k][0];i--){ for(let j=b;j>=grid[k][1];j--){ if(i>=grid[k][0] && j>=grid[k][1]){ dp[i][j]=Math.max(dp[i][j],dp[i-grid[k][0]][j-grid[k][1]]+grid[k][2]) } } } } return(dp[a][b]) }
#!/usr/bin/python # -*- coding: utf-8 -*- ''' Welcome to vivo ! ''' def solution(total_disk,total_memory,app_list): disks=[] mems=[] users=[] for x in app_list: disks.append(x[0]) mems.append(x[1]) users.append(x[2]) n = len(app_list) dp = [[[0]*(mem+1) for _ in range(disk+1)] for _ in range(n+1)] for i in range(1,n+1): for j in range(1,disk+1): for k in range(1,mem+1): if j-disks[i-1]>=0 and k-mems[i-1]>=0: dp[i][j][k] = max(dp[i - 1][j][k],dp[i - 1][j - disks[i-1]][k - mems[i-1]]+ users[i-1]) else: dp[i][j][k] = dp[i-1][j][k] #不选 return dp[-1][-1][-1] if __name__ == "__main__": input1 = input() disk = int(input1.split()[0]) mem = int(input1.split()[1]) input2 = input1.split()[2] app_list = [[int(j) for j in i.split(',')] for i in input2.split('#')] print(solution(disk,mem,app_list))
//1、一台服务器的磁盘空间、内存是固定的,现在有N个应用程序要部署; //2、每个应用程序所需要的磁盘、内存不同,每个应用程序允许访问的用户数也不同,且同一个应用程序不能在一台服务器上部署多个。 //对于一台服务器而言,如何组合部署应用程序能够使得单台服务器允许访问的用户数最多? // //输入描述 : //输入包括三个参数,空格分隔,分别表示服务器的磁盘大小、内存大小,以及应用程序列表; //其中第三个参数即应用程序列表,表述方式为:多个应用程序信息之间用 '#' 分隔,每个应用程序的信息包括 ',' 分隔的部署所需磁盘空间、内存、允许访问的用户量三个数字;比如 50, 20, 2000 表示部署该应用程序需要50G磁盘空间,20G内存,允许访问的用户数是2000 // //输出描述 : //单台服务器能承载的最大用户数 // //输入例子1 : //15 10 5, 1, 1000#2, 3, 3000#5, 2, 15000#10, 4, 16000 // //输出例子1: //31000 // //例子说明1 : // 组合部署服务5, 2, 15000、10, 4, 16000 ,可以让单台服务器承载最大用户数31000 /* 二维背包问题,动态规划求解 */ #include <iostream> #include <cstdio> #include <cstdlib> #include <algorithm> using namespace std; /* * Welcome to vivo ! */ int getCountOfApp(const char* input) { if (nullptr == input) { return 0; } int cnt = 0; for (int i = 0; input[i] != 0; ++i) { if (input[i] == ',') { ++cnt; } } return cnt / 2; } //id start from 0 int getPositionOfApp(const char* input, const int id) { int cntOfComma = id * 2 + 1; int i = 0; for (; input[i] != 0 && cntOfComma != 0; ++i) { if (input[i] == ',') { --cntOfComma; } } while (input[--i] != ' '&&input[i] != '#'); return i + 1; } #define APP_MAX 1000 #define DP_MAX 2048 int disks[APP_MAX]; int mems[APP_MAX]; int users[APP_MAX]; int dp[DP_MAX][DP_MAX]; int solution(const char* input) { const int countOfApp = getCountOfApp(input); if (0 == countOfApp) { return 0; } int res = 0; int disk = 0; int mem = 0; sscanf(input, "%d %d", &disk, &mem); for (int i = 0; i< countOfApp; ++i) { const int pos = getPositionOfApp(input, i); sscanf(input + pos, "%d,%d,%d", &disks[i], &mems[i], &users[i]); } // TODO Write your code here! int N = countOfApp; for (int i = 0; i < N; i++) { for (int j = disk; j >= disks[i]; j--) { for (int k = mem; k >= mems[i]; k--) { dp[j][k] = max(dp[j][k], dp[j - disks[i]][k - mems[i]] + users[i]); } } } return dp[disk][mem]; } int main(int argc, char* args[]) { char input[10000]; cin.getline(input, 10000); cout << solution(input) << endl; return 0; }
#01背包问题的二维限制情况 def solution(total_disk,total_memory,app_list): # TODO Write your code here n = len(app_list) dp = [[0]*(total_memory+1) for _ in range(total_disk+1)] for k in range(n):#对n个物品进行遍历 for i in range(total_disk,-1,-1):#对背包容量进行遍历 for j in range(total_memory,-1,-1): if i>=app_list[k][0] and j>=app_list[k][1]: dp[i][j] = max(dp[i][j],dp[i-app_list[k][0]][j-app_list[k][1]]+app_list[k][2]) return dp[-1][-1] if __name__ == "__main__": input1 = input() disk = int(input1.split()[0]) memory = int(input1.split()[1]) input2 = input1.split()[2] app_list = [[int(j) for j in i.split(',')] for i in input2.split('#')] print(solution(disk,memory,app_list))
private static int solution(int totalDisk, int totalMemory, List<Service> services) { // TODO Write your code here int[][][] u = new int[services.size()+1][totalDisk+1][totalMemory+1]; Service s; // d[i]>D u[i][D][M]=u[i-1][D][M],m[i]>M u[i][D][M]=u[i-1][D][M], // d[i]<=D u[i][D][M]=max{u[i-1][D][M],u[i-1][D-d[i]][M-m[i]]+s[i]} for(int i=1;i<=services.size();i++){ for(int D=1;D<=totalDisk;D++){ for(int M=1;M<=totalMemory;M++){ s=services.get(i-1); if(s.getDisk()>D||s.getMemory()>M) u[i][D][M]=u[i-1][D][M]; else u[i][D][M]=Math.max(u[i-1][D][M],u[i-1][D-s.getDisk()][M-s.getMemory()]+s.getusers()); } } } return u[services.size()][totalDisk][totalMemory]; }
class Solution { /* @param str: 输入字符串序列 @return int: 返回正确的结果 */ public int func(String str) { int Maxcount=0; String[]str1=str.split(" "); int n=Integer.valueOf(str1[0]); int m=Integer.valueOf(str1[1]); String[]str2=str1[2].split("#"); int[][]num=new int[str2.length][3]; for(int i=0;i<str2.length;i++) { String[]str3=str2[i].split(","); for(int j=0;j<str3.length;j++) { int a=Integer.parseInt(str3[j]); num[i][j]=a; } } for(int i=0;i<num.length;i++) { for(int j=i+1;j<num.length;j++) { int sum=num[i][0]+num[j][0]; int sum1=num[i][1]+num[j][1]; if(sum<=n&&sum1<=m) { int count=num[i][2]+num[j][2]; if(count>Maxcount)Maxcount=count; } } } return Maxcount; } }