https://odzkskevi.qnssl.com/09c2b66468470898f860c2625578fbf4?v=1491547520
题意大体是要医治一些牙,每一个牙龈上会有好多颗牙,治这颗牙的前提是把牙龈治好,治某个有对应的花费,治某颗牙有对应的花费
跟julyc学的二维dp
dp[i][j] 表示在只能医治前i个牙龈的条件下,治好j个牙的最小花费
同时开了个num【i】【j】表示在治好j颗牙的最小花费里,第i个牙龈上治好了多少颗
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<string>
#include<algorithm>
#include<queue>
#include<vector>
#include<map>
#include<set>
#define eps 1e-9
#define PI 3.141592653589793
#define bs 1000000007
#define bsize 256
#define inf 0x3f3f3f3f
#define MEM(a) memset(a,0,sizeof(a))
typedef long long ll;
using namespace std;
int dp[605][605],num[605][605];
vector<pair<int ,int > >w[605];
int a[605];
int cmp(pair<int,int> a,pair<int,int> b)
{
return a.second<b.second;
}
int main()
{
int n,k,i,j,u,v,z,m;
scanf("%d %d %d",&n,&k,&m);
for(i=1;i<=k;i++)
scanf("%d",&a[i]);
for(i=1;i<=n;i++)
{
scanf("%d %d",&u,&v);
w[v].push_back(make_pair(i,u));
}
for(i=1;i<=k;i++)
sort(w[i].begin(),w[i].end(),cmp);
memset(dp,inf,sizeof(dp));
for(i=1;i<=k;i++)
{
for(j=1;j<w[i].size();j++)
{
w[i][j].second+=w[i][j-1].second;
}
}
dp[0][0]=0;
for(i=1;i<=k;i++)
{
dp[i][0]=0;
for(j=1;j<=n;j++)
{
dp[i][j]=dp[i-1][j];
}
for(j=1;j<=n;j++)
{
for(z=1;z<=w[i].size()&&z<=j;z++)
{
if(dp[i][j]>dp[i-1][j-z]+w[i][z-1].second+a[i])
{
num[i][j]=z;
dp[i][j]=dp[i-1][j-z]+w[i][z-1].second+a[i];
}
}
}
}
for(i=0;i<=n;i++)
{
if(dp[k][i+1]>m)
{
int x=i,now=k;
printf("%d\n",i);
for(j=1;j<=k;j++)
{
for(z=0;z<num[now][x];z++)
{
printf("%d ",w[now][z].first);
}
x-=num[now][x];
now--;
}
printf("\n");
return 0;
}
}
return 0;
}