小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;
}
}