304. Mars Stomatology
Time limit per test: 1 second(s)
Memory limit: 65536 kilobytes
Memory limit: 65536 kilobytes
input: standard
output: standard
output: standard
Martian girl Kate has a toothache. The martian anatomy is very specific. They all have N teeth, each situated on one of K gums. Kate should pay dentist Ai mars euros for the treatment of i-th tooth. Moreover, Kate should pay Bj euros for the anesthesia of the gum j if this gum has at least one tooth cured. What is the maximal number of teeth Kate can cure if parents gave her P mars euros?
Input
The first line of the input contains three integer numbers N, K and P (1≤ N≤
600; 1≤ K≤ N;
1≤ P≤ 106).
The second line contains the sequence of K integer
numbers B1, B2,..., BK,
where Bj is
the cost of anesthesia of the j-th gum
(1≤ Bj≤
600 for all j = 1, 2,..., K).
Each of the following N lines contains
the description of tooth. Each description is the pair of integer numbers Ai and Ci,
where Ai is
the cost of curing of the i-th tooth, Ci is
the number of the gum the tooth occupies (1≤ Ai≤
600; 1≤ Ci≤ K for
all i = 1, 2,..., N).
Output
Write to the first line of the output the maximal number of cured teeth S.
Write to the second line S numbers of
the cured teeth from the given set. If there are several solutions output any of them.
Example(s)
sample input |
sample output |
4 2 101 21 25 23 13 2 |
34 3 1 |
分析:dp[i][j]表示前i个tooth,修理j个的最小花费
#include<cstdio>
#include<algorithm>
using namespace std;
const int N=601;
const int INF=0x7fffffff;
struct tooth
{
int c,b,id;
bool operator<(tooth t)const{
if(b!=t.b)return b<t.b;
else return c>t.c;
}
}t[N];
int g[N],pre[N],cost[N],dp[N][N],s[N][N];
int n,k,p;
void print(int x,int y)
{
int i;
if(x==0)return;
for(i=s[x][y]+1;i<=x;i++) printf("%d ",t[i].id);
print(pre[x],y-(x-s[x][y]));
}
int main()
{
int i,j,k;
while(~scanf("%d%d%d",&n,&k,&p))
{
for(i=1;i<=k;i++)scanf("%d",&g[i]);
for(i=1;i<=n;i++){scanf("%d%d",&t[i].c,&t[i].b);t[i].id=i;}
sort(t+1,t+n+1);
for(i=1;i<=n;i++)
{
cost[i]=cost[i-1]+t[i].c;
if(t[i].b!=t[i-1].b) j=i-1;
pre[i]=j;
}
for(i=1;i<=n;i++)for(j=0;j<=i;j++)
{
dp[i][j]=INF;
for(k=pre[i];k<=i;k++)
{
int t1=i-k,t2=j-t1;
if(j>=t1&&t2<=pre[i])
{
if(dp[pre[i]][t2]+cost[i]-cost[k]+g[t[i].b]*(i!=k)<dp[i][j])
{
dp[i][j]=dp[pre[i]][t2]+cost[i]-cost[k]+g[t[i].b]*(i!=k);
s[i][j]=k;
}
}
}
}
for(i=n;i>0;i--)
{
if(dp[n][i]<=p)
{
printf("%d\n",i);
print(n,i);
break;
}
}
if(i==0) puts("0");
}
return 0;
}