I NEED A OFFER!
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 35537 Accepted Submission(s): 14339
Problem Description
Speakless很早就想出国,现在他已经考完了所有需要的考试,准备了所有要准备的材料,于是,便需要去申请学校了。要申请国外的任何大学,你都要交纳一定的申请费用,这可是很惊人的。Speakless没有多少钱,总共只攒了n万美元。他将在m个学校中选择若干的(当然要在他的经济承受范围内)。每个学校都有不同的申请费用a(万美元),并且Speakless估计了他得到这个学校offer的可能性b。不同学校之间是否得到offer不会互相影响。“I NEED A OFFER”,他大叫一声。帮帮这个可怜的人吧,帮助他计算一下,他可以收到至少一份offer的最大概率。(如果Speakless选择了多个学校,得到任意一个学校的offer都可以)。
Input
输入有若干组数据,每组数据的第一行有两个正整数n,m(0<=n<=10000,0<=m<=10000)
后面的m行,每行都有两个数据ai(整型),bi(实型)分别表示第i个学校的申请费用和可能拿到offer的概率。
输入的最后有两个0。
Output
每组数据都对应一个输出,表示Speakless可能得到至少一份offer的最大概率。用百分数表示,精确到小数点后一位。
Sample Input
10 3
4 0.1
4 0.2
5 0.3
0 0
Sample Output
44.0%
Hint
You should use printf(“%%”) to print a ‘%’.
思路:动态规划,01背包解决,状态转移方程;dp[j] = min(dp[j], dp[j - money[i]] * (1 - probability[i]))//寻找概率最小的,之前用二位数组做超时。
HDU2602-01背包
//#include<iostream> //#include<stdlib.h> //#include<string.h> //using namespace std; //const int maxnum = 10009; //int Money, N; //int Max_Value = 0; //int money[maxnum]; //double probability[maxnum]; //double dp[maxnum][maxnum]; //#define max(x,y)(x)>(y)?(x):(y); //void DP() //{ // int i, j; // for (i = 0; i <= maxnum; i++) // { // for (j = 0; j <= maxnum; j++) // { // dp[i][j] = 1.0; // } // } // for (i = 1; i <= N; i++) // { // for (j = 0; j <= Money; j++) // { // if (j < money[i]) // { // dp[i][j] = dp[i - 1][j]; // } // else // { // if (dp[i-1][j]>(dp[i-1][j - money[i]])*(1-probability[i])) // { // dp[i][j] = (dp[i - 1][j - money[i]])*(1 - probability[i]); // } // else // { // dp[i][j] = dp[i - 1][j]; // } // } // } // } // printf("%.1lf%% ", (1 - dp[N][Money]) * 100); //} // // //int main() //{ // while ((cin >> Money >> N)) // { // if (money == 0 || N == 0) // break; // for (int i = 1; i <= N; i++) // { // cin >> money[i] >> probability[i]; // } // DP(); // } // // return 0; //} #include<iostream> #include<stdlib.h> #include<string.h> using namespace std; const int maxnum = 10009; int Money, N; int Max_Value = 0; int money[maxnum]; double probability[maxnum]; double dp[maxnum]; #define min(x,y)(x)>(y)?(y):(x); void DP() { int i, j; for (i = 0; i <= maxnum; i++)//数组初始化为1 { dp[i] = 1.0; } for (i = 1; i <= N; i++) { for (j = Money; j >= money[i]; --j) { dp[j] = min(dp[j], dp[j - money[i]] * (1 - probability[i]))//寻找概率最小的 } } printf("%.1lf%% ", (1 - dp[Money]) * 100); } int main() { while (cin>>Money>>N, Money != 0 || N != 0) { for (int i = 1; i <= N; i++) { cin >> money[i] >> probability[i]; } DP(); } return 0; }