您的位置:首页 > 其它

codeforce 416C Booking System

2016-04-11 22:20 453 查看
原题地址

题意

一家餐馆有K张桌子,每张桌子有最大容量ri;

有N份订单,每份订单有人数和钱

要求每份订单的人必须坐在一张桌子上,否则无法接受该订单

问怎样使钱数最大

#include<bits/stdc++.h>

using namespace std;
const int maxn=1000;

struct Request
{
int p;
int c;
int id;
};
struct P
{
int r;
int id;
};

Request re[maxn+5];
P p[maxn+5];
int dp[maxn+5][maxn+5];

bool cmp(const Request &a,const Request &b)
{
return a.c>b.c;
}
bool cmp2(const P &a,const P &b)
{
return a.r>b.r;
}
void print_ans(int n,int i,int j,int m,int s);

int main(void)
{
#ifdef ex
freopen ("in.txt","r",stdin);
#endif

int n,k;
int m,s;

scanf("%d",&n);
for (int i=1;i<=n;++i)
{
scanf("%d%d",&re[i].c,&re[i].p);
re[i].id=i;
}
scanf("%d",&k);
for (int i=1;i<=k;++i)
{
scanf("%d",&p[i].r);
p[i].id=i;
}

sort(p+1,p+k+1,cmp2);
sort(re+1,re+n+1,cmp);

re[0]=(Request){100000,1000000,n+1};

for (int i=n;i>=0;--i)
{
for (int j=k;j>=1;--j)
{
if (p[j].r>=re[i].c)
{
dp[i][j]=max(dp[i+1][j],dp[i+1][j+1]+re[i].p);
}
else
{
dp[i][j]=dp[i+1][j];
}
}
}
s=dp[0][1];

print_ans(n,0,1,0,s);

}

void print_ans(int n,int i,int j,int m,int s)
{
if (i==n+1)
{
printf("%d %d\n",m,s);
return;
}
else if (dp[i][j]==dp[i+1][j])
{
print_ans(n,i+1,j,m,s);
}
else if (dp[i][j]==dp[i+1][j+1]+re[i].p)
{
print_ans(n,i+1,j+1,m+1,s);
printf("%d %d\n",re[i].id,p[j].id);
}
}


题解

DP

为了使DP的决策有序化,先把订单和桌子容量排序

然后转移就好了

问题出在路径打印上,一是打印的路径编号是排序后的而非原来的导致WA,二是打印函数两个else if 的次序不同会导致WA,还没想清楚为什么

下面的代码用回朔法打印路径,比较好写一点,智障的递归水平非常糟糕啊……

#include<bits/stdc++.h>

using namespace std;
const int maxn=1000;

struct Request
{
int p;
int c;
int id;
};
struct P
{
int r;
int id;
};
struct Cood
{
int i;
int j;
};

Request re[maxn+5];
P p[maxn+5];
Cood t[maxn+5][maxn+5];
Cood ans[maxn+5];
int dp[maxn+5][maxn+5];

bool cmp(const Request &a,const Request &b)
{
return a.c>b.c;
}
bool cmp2(const P &a,const P &b)
{
return a.r>b.r;
}
void print_ans(int n,int i,int j,int m,int s);

int main(void)
{
#ifdef ex
freopen ("in.txt","r",stdin);
#endif

int n,k;
int m,s;

scanf("%d",&n);
for (int i=1;i<=n;++i)
{
scanf("%d%d",&re[i].c,&re[i].p);
re[i].id=i;
}
scanf("%d",&k);
for (int i=1;i<=k;++i)
{
scanf("%d",&p[i].r);
p[i].id=i;
}

sort(p+1,p+k+1,cmp2);
sort(re+1,re+n+1,cmp);

re[0]=(Request){100000,1000000,n+1};

for (int i=n;i>=0;--i)
{
for (int j=k;j>=1;--j)
{
if (p[j].r>=re[i].c)
{
if (dp[i+1][j+1]+re[i].p>dp[i+1][j])
{
dp[i][j]=dp[i+1][j+1]+re[i].p;
t[i][j]=(Cood){i+1,j+1};
}
else
{
dp[i][j]=dp[i+1][j];
t[i][j]=(Cood){i+1,j};
}
}
else
{
dp[i][j]=dp[i+1][j];
t[i][j]=(Cood){i+1,j};
}
}
}
s=dp[0][1];

m=0;
Cood st=t[0][1];

while (1)
{
int i=st.i;
int j=st.j;
st=t[i][j];
if (st.j-j==1)
{
++m;
ans[m]=(Cood){re[i].id,p[j].id};
}
if (i==n) break;
}

printf("%d %d\n",m,s);
for (int i=1;i<=m;++i)
{
printf("%d %d\n",ans[i].i,ans[i].j);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: