题目描述
PIPI有一台笔记本电脑,一台台式机电脑,两台电脑的性能相同,现在小明手里有N个等待运行的程序,每个程序运行所需的时间分别为n1,n2,n3,n4……,一台电脑同一时刻只能运行一个程序,一个程序只需要运行一次。两台电脑同时开始运行,请问小明该如何分配程序在这两台电脑上运行,使得最后结束运行的电脑的运行时间最短。
输入
输入不超过30组数据,每组数据第一行为N,代表有N个等待运行的程序,第二行为N个数字,代表每个程序的运行时间,1 <= N <= 1000 ,每个程序的运行时间均为正整数, 所有程序的运行时间之和不超过5000。
输出
输出最后结束运行的电脑的运行时间。
样例输入
2
1 1
2
1 2
3
1 2 3
样例输出
1
2
3
贪心不行,是01背包问题
即只有一台电脑时依次运行需要运行的时间的一半,最多可以运行多长
总数减去一半最多耗时,即答案,另一台电脑需要的最长时间
01背包问题
#include
#include
#include
#include
using namespace std;
int N;
int arr[1005];
int sum,mid;
int dp[1005][2510];
int main(){
int i,j;
while(scanf("%d",&N)!=EOF){
sum=0;
memset(dp,-1,sizeof(dp));
for(i=1;i<=N;i++){
scanf("%d",&arr[i]);
sum+=arr[i];
dp[i][0]=0;
}
dp[0][0]=0;
mid=sum/2;
for(i=1;i<=mid;i++)dp[0][i]=0;
for(i=1;i<=N;i++)
for(j=1;j<=mid;j++)
if(j<arr[i]) dp[i][j]=dp[i-1][j];
else dp[i][j]=max(dp[i-1][j],dp[i-1][j-arr[i]]+arr[i]);
printf("%d\n",sum-dp[N][mid]);
}//while
return 0;
}
#include
#include
#include
#include
using namespace std;
int a[1005],dp[5005];
int main(){
int n;
while(scanf("%d",&n)!=EOF){
memset(dp,0,sizeof(dp));
int sum=0;
for(int i=0;i<n;i++) scanf("%d",&a[i]),sum+=a[i];
int ans=sum;
sum/=2;
sort(a,a+n);
dp[0]=1;
for(int i=0;i<n;i++)
for(int j=sum;j>=a[i];j--)
if(dp[j-a[i]]) dp[j]=1;
for(int i=sum;;i--)
if(dp[i]) {printf("%d\n",ans-i);break;}
}
}
1076: 饭卡
题目描述
CSU本部食堂的饭卡有一种很诡异的设计——在购买之前判断余额。如果购买一个商品之前,卡上的剩余金额大于或等于5元,就一定可以购买成功(即使购买后卡上余额为负),否则无法购买(即使金额足够)。所以大家都希望尽量使卡上的余额最少。
某天,食堂中有n种菜出售,每种菜可购买一次。已知每种菜的价格以及卡上的余额,问最少可使卡上的余额为多少。
输入
多组数据。对于每组数据:
第一行为正整数n,表示菜的数量。n<=1000。
第二行包括n个正整数,表示每种菜的价格。价格不超过50。
第三行包括一个正整数m,表示卡上的余额。m<=1000。
输出
对于每组输入,输出一行,包含一个整数,表示卡上可能的最小余额。
样例输入
1
50
5
10
1 2 3 2 1 1 2 3 2 1
50
样例输出
-45
32
把最贵的菜留五块钱最后买即可使余额最少
即转化为money-5的从1到n-1中选择的01背包问题
要注意的是,如果money<5,则直接输出money(因为什么也买不了ovO)
#include
#include
#include
#include
#include
using namespace std;
int cmp(const void *a,const void *b){
return (*(int*)a-*(int*)b);
}
int N;
int cost[1005];
int dp[1005][1005];
int money;
int main(){
int i,j;
while(scanf("%d",&N)!=EOF){
for(i=1;i<=N;i++)
scanf("%d",&cost[i]);
scanf("%d",&money);
if(money<5) {printf("%d\n",money);continue;}
qsort(cost+1,N,sizeof(int),cmp);
money-=5;
for(i=0;i<N;i++) dp[i][0]=0;
for(i=1;i<=money;i++)dp[0][i]=0;
for(i=1;i<N;i++)
for(j=1;j<=money;j++)
if(j<cost[i]) dp[i][j]=dp[i-1][j];
else dp[i][j]=max(dp[i-1][j],dp[i-1][j-cost[i]]+cost[i]);
printf("%d\n",money+5-dp[N-1][money]-cost[N]);
}
return 0;
}
1079
#include
#include
int n,m,val[500],wei[500];
int dp[10005];
int main(){
int i,j;
while(scanf("%d %d",&n,&m)!=EOF){
for(i=0;i<n;i++)
scanf("%d %d",&val[i],&wei[i]);
memset(dp,0,sizeof(dp));
for(i=0;i<n;i++)
for(j=wei[i];j<=m;j++)
if(dp[j-wei[i]]||j==wei[i]) if(dp[j]==0||dp[j]>dp[j-wei[i]]+val[i]) dp[j]=dp[j-wei[i]]+val[i];
if(dp[m]==0) printf("impossible\n");
else printf("%d\n",dp[m]);
}
return 0;
}