您的位置:首页 > Web前端

poj 1170-Shopping Offers解题报告

2012-05-19 00:05 423 查看
链接:http://poj.org/problem?id=1170

很经典的状态dp,这道题基本上体现了状态dp的全部处理过程,状态进制的确定过程,主要是根据题中的数据范围,状态产生要根据输入的状态产生,中间状态合法性判断,对状态的计算处理,然后才是dp里的最优子结构选择问题,当然了要保证一个选择只有一种状态,这是肯定的。最后就是结果的处理过程。

View Code

#include<iostream>
#include<cstdio>
#include<cstring>
#define inf 0x7fffffff
#define min(x,y) x<y?x:y
using namespace std;
int b[7]={1,6,36,216,1296,7776,46656};
struct good
{
int code,num,price;
}basket[5];
struct sta
{
int state;
int price;
}offer[100];
int n,num,state;
int flag[1000];
int dp[46656];
bool cheack(int p1,int p2)//两个状态能否相加的合法性判断
{
int i;
for(i=0;i<n;i++)
{
if((p1%6+p2%6)>basket[i].num)
return false;
p1/=6;
p2/=6;
}
return true;
}
int cal(int p)//状态产生价值计算
{
int i;
int sum=0;
for(i=0;i<n;i++)
{
sum+=(p%6)*basket[i].price;
p/=6;
}
return sum;
}
int main()
{
int i,j,k,ans,num;
while(scanf("%d",&n)!=EOF)
{
state=0;
for(i=0;i<1000;i++)
flag[i]=6;
memset(basket,0,sizeof(basket));
for(i=0;i<n;i++)
{
scanf("%d%d%d",&basket[i].code,&basket[i].num,&basket[i].price);
flag[basket[i].code]=i;
state+=basket[i].num*b[i];//状态的产生
}
scanf("%d",&num);
int goodnum,temp,tempco;
memset(offer,0,sizeof(offer));
for(i=0;i<num;i++)
{
scanf("%d",&goodnum);
for(j=0;j<goodnum;j++)
{
scanf("%d%d",&tempco,&temp);
offer[i].state+=b[flag[tempco]]*temp;//单个状态的产生
}
scanf("%d",&offer[i].price);
}
for(i=0;i<=state;i++)
dp[i]=inf;
dp[0]=0;
for(i=0;i<num;i++)
for(j=0;j<=state;j++)
{
if(dp[j]==inf)
continue;
if(j+offer[i].state<=state&&cheack(j,offer[i].state))//最优值选择
dp[j+offer[i].state]=min(dp[j]+offer[i].price,dp[j+offer[i].state]);
}
ans=inf;
for(i=0;i<=state;i++)//最后产生结果的处理
{
if(dp[i]==inf)
continue;
ans=min(dp[i]+cal(state-i),ans);
}
printf("%d\n",ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: