题意
一家餐馆有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);
}
}