首页 > 代码库 > D - FATE HDU-2159 FATE 二维背包
D - FATE HDU-2159 FATE 二维背包
Description
Input
Output
Sample Input
Sample Output
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
struct dp_node
{
int value;
int total_num;
};
struct dp_node dp[105][105];
struct node
{
int tolerate;
int exp;
double rati;
friend bool operator<(node a,node b)
{
return a.rati>b.rati;
}
};
struct node num[105];
int main()
{
int n,m,k,s;
while(scanf("%d%d%d%d",&n,&m,&k,&s)!=EOF)
{
for(int i=1;i<=k;i++)
{
scanf("%d%d",&num[i].exp,&num[i].tolerate);
num[i].rati=num[i].exp*1.0/num[i].tolerate;
}
// sort(num,num+k);
for(int j=0;j<105;j++)
{
dp[0][j].value=http://www.mamicode.com/0;
dp[0][j].total_num=0;
dp[j][0].value=http://www.mamicode.com/0;
dp[j][0].total_num=0;
}
for(int i=1;i<=k;i++)
{
for(int j=num[i].tolerate;j<=m;j++)
{
dp[i][j].value=http://www.mamicode.com/dp[i-1][j].value;
dp[i][j].total_num=dp[i-1][j].total_num;
for(int ak=0;ak<=j/num[i].tolerate;ak++)
{
if(dp[i][j].value<dp[i-1][j-ak*num[i].tolerate].value+ak*num[i].exp)
{
dp[i][j].value=http://www.mamicode.com/dp[i-1][j-ak*num[i].tolerate].value+ak*num[i].exp;
dp[i][j].total_num=dp[i-1][j-ak*num[i].tolerate].total_num+ak;
}
}
}
}
for(int i=0;i<=m;i++)
{
// printf("%d\n",dp[k][i].value);
if(dp[k][i].value>=n&&dp[k][i].total_num<=s)
{
printf("%d\n",m-i);
break;
}
if(i==m)
{
printf("-1\n");
}
}
}
return 0;
}
然后,后面用二维扩展背包,果然一下就过了,所以有时候,经典的问题,还是有其一般性与特点的。
这个的一般性主要体现在第二重循环中,通过这个循环很好的解决了一般性问题,同时也强掉了状态转移方程的重要性。
这时正确的代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
struct node
{
int tolerate;
int exp;
double rati;
friend bool operator<(node a,node b)
{
return a.rati>b.rati;
}
};
struct node num[105];
int dp[105][105];
int main()
{
int n,m,k,s;
while(scanf("%d%d%d%d",&n,&m,&k,&s)!=EOF)
{
for(int i=1;i<=k;i++)
{
scanf("%d%d",&num[i].exp,&num[i].tolerate);
num[i].rati=num[i].exp*1.0/num[i].tolerate;
}
memset(dp,0,sizeof(dp));
for(int i=1;i<=k;i++)
{
for(int j=num[i].tolerate;j<=m;j++)
{
for(int ak=1;ak<=s;ak++)
{
if(dp[j][ak]<dp[j-num[i].tolerate][ak-1]+num[i].exp)
dp[j][ak]=dp[j-num[i].tolerate][ak-1]+num[i].exp;
}
}
}
for(int i=0;i<=m;i++)
{
if(dp[i][s]>=n)
{
printf("%d\n",m-i);
break;
}
if(i==m)
printf("-1\n");
}
}
return 0;
}
D - FATE HDU-2159 FATE 二维背包