标签:
1 /* 2 3 题意 : M个人 看守 N个 仓库,每个人有个能力值p[i],仓库的安全值 = 能力值/看守的仓库数 , 4 聘请某人的花费就是他的能力值,求最高的安全值和最小花费。 5 6 两次DP,一次求最高安全值,在根据安全值求最小花费。 7 dp[j]表示 i 个人看守j个仓库的最高安全值 8 */ 9 10 #include<cstdio> 11 #include<cstring> 12 #include<algorithm> 13 using namespace std; 14 const int INF=0x3f3f3f3; 15 int dp[1010],p[50]; 16 int main() 17 { 18 int n,m,ans=0; 19 while(scanf("%d%d",&n,&m)!=EOF) 20 { 21 if(!n && !m) return 0; 22 for(int i=0;i<m;i++) 23 scanf("%d",&p[i]); 24 memset(dp,0,sizeof(dp)); 25 dp[0]=INF; 26 for(int i=0;i<m;i++) 27 for(int j=n;j>=0;j--) 28 for(int k=1;k<=j && k<=p[i];k++) 29 dp[j]=max(dp[j],min(dp[j-k],p[i]/k)); 30 ans=dp[n]; 31 if(ans>0) 32 { 33 for(int i=1;i<=n;i++) dp[i]=INF; 34 dp[0] = 0; 35 for(int i=0;i<m;i++) 36 for(int j=n;j>=0;j--) 37 for(int k=min(j,p[i]/ans);k>0;k--) 38 dp[j]=min(dp[j],dp[j-k]+p[i]); 39 printf("%d %d\n",ans,dp[n]) ; 40 } 41 else printf("0 0\n"); 42 } 43 return 0; 44 }
标签:
原文地址:http://www.cnblogs.com/ember/p/4963044.html