Weights and Measures(贪心+动态规划)
I know, up on top you are seeing great sights,
But down at the bottom, we, too, should have rights.
We turtles can’t stand it. Our shells will all crack!
Besides, we need food. We are starving!” groaned Mack.
Mack, in an effort to avoid being cracked, has enlisted your advice as to the order in which turtles
should be dispatched to form Yertle’s throne. Each of the five thousand, six hundred and seven turtles
ordered by Yertle has a different weight and strength. Your task is to build the largest stack of turtles
possible.
Input
Standard input consists of several lines, each containing a pair of integers separated by one or more
space characters, specifying the weight and strength of a turtle. The weight of the turtle is in grams.
The strength, also in grams, is the turtle’s overall carrying capacity, including its own weight. That is,
a turtle weighing 300g with a strength of 1000g could carry 700g of turtles on its back. There are at
most 5,607 turtles.
Output
Your output is a single integer indicating the maximum number of turtles that can be stacked without
exceeding the strength of any one.
Sample Input
300 1000
1000 1200
200 600
100 101
Sample Output
3
題意:有幾只烏龜,每只烏龜有一定的重量與力量。每只烏龜可以背小于它力量的重量(包括它自身的重量)。問最多一共可以有多少只烏龜疊在一起。
可以證明,將力量大的烏龜放在下面可以得到一個更優的狀態。因此在dp之前應先將所有烏龜按力量大小排好序,力量小的在前面。
首先,我們不妨證明一下這個命題,如果一個力量小的烏龜可以馱著一個力量大的烏龜,那么這個力量大的烏龜也必然可以馱起這個力量小的烏龜,而且還能夠使兩個烏龜上方增加承重能力。
1.用dp[i][j]表示從前 i 只烏龜中選出 j 只可以得打的最小總重量。
轉移方程為:如果dp[i-1][j-1]+t[i].w <=t[i].s,dp[i][j] = min( dp[i-1][j-1]+t[i].w, dp[i-1][j] ); 如果不等,則dp[i][j] = dp[i-1][j];
代碼如下:
#include <iostream> #include <cstdio> #include <string.h> #include <cmath> #include <algorithm> using namespace std;int dp[5650][5650]; typedef struct {int w, s; }tur; tur t[5650]; int n; bool comp( tur a, tur b) {if( a.s <b.s||(a.s==b.s&& a.w< b.w))return true;return false; } int main() {n=0;while( scanf("%d%d",&t[n].w,&t[n].s )!=EOF )n++;sort( t, t+n, comp);int i,j;memset( dp, 0x7f, sizeof( dp));for( i=0; i<=n; i++)dp[i][0] =0;for( i=1; i<=n; i++)for( j=1;j<=i; j++){if(dp[i-1][j] <dp[i][j])dp[i][j] =dp[i-1][j];if( dp[i-1][j-1]+t[i-1].w <=t[i-1].s &&dp[i-1][j-1]+t[i-1].w<dp[i][j] )dp[i][j] =dp[i-1][j-1]+t[i-1].w;}for( i=n; i>=0; i--)if( dp[n][i]<(1<<30))break;printf("%d\n",i);return 0; }努力加油a啊,(o)/~
總結
以上是生活随笔為你收集整理的Weights and Measures(贪心+动态规划)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 算法训练 未名湖边的烦恼(递推)
- 下一篇: 游戏(CCF)