标签:
Time Limit: 1500MS | Memory Limit: 30000K | |||
Total Submissions: 1580 | Accepted: 401 | Special Judge |
Description
Input
Output
Sample Input
5 10.0 50.0 90.0 38.0 7.1 0
Sample Output
3 5
Source
题意:给定一定数量的物品和物品的质量,问是否能够把这些物品分成两堆,然后差别不差过2%;
解题思路:因为题目中涉及到了小数,所以不好用dp做,就需要把小数乘以一个数把它变成整数进行背包,在这个题中求出每一个物体的质量占总质量的比值然后乘以2000,再进行一次dp;
1 #include<iostream> 2 #include<algorithm> 3 #include<cstdio> 4 #include<cstring> 5 #include<cstdlib> 6 #include<stack> 7 using namespace std; 8 const int maxn=22010; 9 bool dp[maxn]; 10 int n; 11 double input[107]; 12 int num[107],road[maxn]; 13 double sum; 14 stack<int> s; 15 void init() 16 { 17 memset(dp,0,sizeof(dp)); 18 memset(num,0,sizeof(num)); 19 sum=0; 20 while(!s.empty()) s.pop(); 21 } 22 void DP() 23 { 24 dp[0]=1; 25 for(int i=1;i<=n;i++) 26 { 27 for(int j=10000;j>=0;j--) 28 { 29 if(dp[j]&&!dp[j+num[i]]) dp[j+num[i]]=1,road[j+num[i]]=i; 30 31 } 32 } 33 } 34 int main() 35 { 36 // freopen("in.txt","r",stdin); 37 while(1){ 38 scanf("%d",&n); 39 if(!n) break; 40 init(); 41 double f; 42 for(int i=1;i<=n;i++) scanf("%lf",&input[i]),sum+=input[i]; 43 for(int i=1;i<=n;i++) num[i]=input[i]/sum*20000; 47 DP(); 48 49 int k; 50 for(int i=10000;i>=0;i--) if(dp[i]) {k=i;break;} 51 52 while(k>0){ 53 s.push(road[k]); 54 k-=num[road[k]]; 55 } 56 bool first=1; 57 while(!s.empty()){ 58 if(first) printf("%d",s.top()),first=0; 59 else printf(" %d",s.top()); 60 s.pop(); 61 } 62 printf("\n"); 63 } 64 return 0; 65 }
标签:
原文地址:http://www.cnblogs.com/codeyuan/p/4328371.html