Cat
Time Limit: 1500MS | Memory Limit: 30000K | |||
Total Submissions: 1580 | Accepted: 401 | Special Judge |
Description
In strong winds, sailboats tend to heel leeward (tilt away from the wind) like the one in the picture. Heeling is undesirable for at least two reasons. First, the effective sail area is reduced, as the effective height of the sail is multiplied by the cosine of the angle. Reduced sail area implies reduced speed. Second, the boat may heel to the point that its centre of gravity ceases to be above the hull, causing the boat to capsize.
To mitigate these problems, catamarans like the one shown split the
hull into two pieces (the port and starboard hulls). This design
increases the effective width of the boat. Increased width decreases the
vertical mechanical advantage of the sail, thus reducing heeling.
Increased width also increases the angle of heeling that can be
tolerated before the boat capsizes.
Heeling can also be mitigated by having the crew sit or stand on, or
even hike out beyond, the windward hull. If you look carefully at the
picture you can see the two person crew hiking to windward.
At some wind velocity, even these measures are insufficient to keep
the boat upright. A skipper‘s only choice (other than to capsize) is to
let out the sail, which reduces its effective horizontal dimension much
as heeling reduces its vertical dimension. As with heeling, this action
causes loss of speed. If the boat heels sufficiently, it may not even be
possible to let out the sail, as its outer corner may be obstructed by
the surface of the water!
Reefing is a mechanism for reducing the sail‘s area. Roller reefing
involves wrapping the sail around the boom (much like a window blind) so
as to reduce its height. With sufficient reefing, the heeling can be
controlled in almost any wind.
But reefing involves reduced speed, so our skipper has elected yet
another approach. She has decided to beach the boat and pick up some
rocks to use as ballast. Ballast is just dead weight added to hull,
which tends to counteract heeling. It slows the boat a bit (as it rides
lower in the water) but not nearly so much as reducing sail area.
Given n rocks, you are to compute how to divide them between the
port and starboard hulls so that the weight of rocks in each hull is
nearly equal.
Input
Input
contains several test cases. Each test case begins with 1 < n <=
100; the number of rocks to be added as ballast. Consider the rocks to
be numbered 1 through n. n lines follow; the ith line gives the weight
in kg of the ith rock - a positive real number not greater than 100. A
line containing 0 follows the last test case.
Output
For
each test case, output a single line giving the numbers of the rocks
that should be loaded as ballast into the starboard hull. Assume that
the other rocks will be loaded into the port hull. The total weight of
ballast in the port hull should not differ from that in the starboard
hull by more than 2%. If there are many solutions, any one will do.
There will always be a solution; indeed, there will always be a solution
that balances within 1%, but you aren‘t required to find it.
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 }