Mars Stomatology gym 1007651 补牙(dp)
来源:互联网 发布:java wait notify使用 编辑:程序博客网 时间:2024/05/16 02:05
Problem I. Mars Stomatology
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.
题意 给出n,k,p 代表 坏牙数 棉花数 钱数
给出 棉花价格
给出 补牙价格 补牙所在牙龈
一个棉花可以用于一个牙龈
i代表牙龈,j代表总补牙数,z代表这层的补牙数
状态转移方程 dp[i][j]=min(dp[i][j],dp[i-1][j-z]+sum[i][z]+a[i]*(z!=0));
还要记录路径,怎么记录路径呢。
记录每层缩小的时间补牙的个数就好
最后找到第一个大于p的状态 就可以逆推输出结果了
#include <bits/stdc++.h>using namespace std;int dp[700][700],pre[700][700],sum[700][700];vector<pair<int,int> > v[700];int a[700];const int inf=0x3f3f3f3f;int main(){ int n,k,p; scanf("%d%d%d",&n,&k,&p); for(int i=1;i<=k;i++) scanf("%d",&a[i]); for(int i=1;i<=n;i++) { int c,d; scanf("%d%d",&c,&d); v[d].push_back(make_pair(c,i)); } for(int i=1;i<=k;i++) sort(v[i].begin(),v[i].end()); for(int i=1;i<=k;i++) { for(int j=0;j<v[i].size();j++) sum[i][j+1]=sum[i][j]+v[i][j].first; } memset(dp,inf,sizeof(dp)); dp[0][0]=0; for(int i=1;i<=k;i++) { for(int j=0;j<=n;j++) { for(int z=0;z<=v[i].size();z++) { if(z>j) continue; if(dp[i][j]>dp[i-1][j-z]+sum[i][z]+a[i]*(z!=0)) { pre[i][j]=z; dp[i][j]=min(dp[i][j],dp[i-1][j-z]+sum[i][z]+a[i]*(z!=0)); } } } } for(int i=1;i<=n+1;i++) { if(dp[k][i]>p){ printf("%d\n",i-1 ); int num=i-1; int now=k; while(num) { for(int j=0;j<pre[now][num];j++) printf("%d ",v[now][j].second ); num-=pre[now][num]; now--; } return 0; } } return 0;}
- Mars Stomatology gym 1007651 补牙(dp)
- Mars Stomatology Gym
- SGU 304. Mars Stomatology
- sgu 304 Mars Stomatology
- Gym 100917J Judgement(dp+bitset)
- Gym 100712D Alternating Strings (dp)
- GYM 100182 H.Robot Challenge(dp)
- GYM 101128 E.Wooden Signs(dp)
- GYM 101147 H.Commandos(dp)
- GYM 101061 F.Fairness(dp)
- Gym 100792H Hashing (DP)
- Gym-101201B(bfs+dp)
- GYM 101086 K.Betrayed(树形DP+概率DP)
- 补牙 + 评估
- hdoj Flying to the Mars 1800 (DP)
- 状压DP Gym
- Gym 101490K dp
- Gym 101201B dp
- Android LruCache内存缓存实现详解
- 打开和关闭mysql服务的两种方法
- eigen与matlab对应函数列表
- "o_neww_ww_123"分割字符串split
- java基础学习总结——方法的重载(overload)
- Mars Stomatology gym 1007651 补牙(dp)
- String.replace()方法
- java基础学习总结——static关键字
- Java易混淆的概率:成员变量、类变量、实例变量、局部变量
- java基础学习总结——哈希编码
- js中初始化的事件
- 超链接<a></a>下划线、链接、活动的、悬停的
- java基础学习总结——equals方法
- java基础学习总结——Object类