poj1018 动态规划里面的简单题
其实poj都是跪着刷
对于这个样子的动态规划 因为需要保存两个信息 所以用一个下标来存储其中一个信息 这让我想起了某年蓝桥杯的 一道题 很机智的将数组容量扩大二倍后取一半遍历。直接省去了对负值的处理
每一个带宽作为一个独立的下标 遇到相同下标取 价格最小值就好了
夹杂了初始化中一个无穷大的小技巧0X3F3F3F3F 既可以设置无穷大,又可以使无穷大加上一个数字不会超出限制。
第一组数据出现时需要赋下值
遍历所有可能带宽,在上一层赋初始值的数据下区分两种情况 Z<=B 和其他(b取最小值)
一个比较拿和不拿,另外一个定义新带宽(然后拿不拿(当然不要忘记我们初始化了INF=0x3f3f3f3f)
这样决策表就打完了
最后是输出
结束
上代码
#include <iostream>
#include<memory.h>
#include<algorithm>
#include<iomanip>
using namespace std;
int dp[120][1200];
int main()
{
const int INF = 0x3f3f3f3f;
int t;
cin>>t;
for(int i=0;i<t;i++){//测试样例
int m = 0;
cin>>m;
memset(dp,INF,sizeof(int)*120*1200);
for(int j=1;j<=m;j++){//第J层
int p =0;cin>>p;
for(int k=1;k<=p;k++){//第K个
int B,P;
cin>>B>>P;
if(j==1){
dp[1][B] =min(dp[1][B],P);
}else{
for(int z=0;z<1100;z++)
{
if(dp[j-1][z]!=INF){
if(z<=B){
dp[j][z] = min(dp[j][z],dp[j-1][z]+P);
}else{
dp[j][B] = min(dp[j][B],dp[j-1][z]+P);
}
}
}
}
}
}
double ans = 0;
for(int l=0;l<1100;l++)
{
if(dp[m][l]!=INF){
double temp = (double)l/dp[m][l];
if(temp>ans){
ans = temp;
}
}
}
cout<<fixed<<setprecision(3)<<ans<<endl;
}
return 0;
}