8.18(军训DAY 2)

今天...继续dp

先把昨天没弄懂弄的背包方案数的问题搞懂.....具体就看我对昨天博客的评论了把.

于是开始今天的玄学操作   继续背包   

先练一题试试手

LUOGU1474 货币系统 Money Systems题目描述母牛们不但创建了它们自己的政府而且选择了建立了自己的货币系统。由于它们特殊的思考方式,它们对货币的数值感到好奇。传统地,一个货币系统是由1,5,10,20 或 25,50, 和 100的单位面值组成的。母牛想知道有多少种不同的方法来用货币系统中的货币来构造一个确定的数值。举例来说, 使用一个货币系统 {1,2,5,10,...}产生 18单位面值的一些可能的方法是:18x1, 9x2, 8x2+2x1, 3x5+2+1,等等其它。 写一个程序来计算有多少种方法用给定的货币系统来构造一定数量的面值。保证总数将会适合long long (C/C++) 和 Int64 (Free Pascal),即在0 到2^63-1之间。

毕竟昨天刚刚动这个方案数  今天还是要做个题目练练手的..02背包的这道题  和昨天一样 01回了02、多重的基础题就比较简单了。很快就过掉了  然后我就遇到了今天的第一瓶颈:

第二题 LUOGU2725 邮票 Stamps

题目背景:给一组 N 枚邮票的面值集合(如,{1 分,3 分})和一个上限 K —— 表示信封上能够贴 K 张邮票。计算从 1 到 M 的最大连续可贴出的邮资。例如,假设有 1 分和 3 分的邮票;你最多可以贴 5 张邮票。很容易贴出 1 到 5 分的邮资(用 1 分邮票贴就行了),接下来的邮资也不难

6 = 3 + 3 
7 = 3 + 3 + 1 
8 = 3 + 3 + 1 + 1 
9 = 3 + 3 + 3 
10 = 3 + 3 + 3 + 1 
11 = 3 + 3 + 3 + 1 + 1 
12 = 3 + 3 + 3 + 3 

13 = 3 + 3 + 3 + 3 + 1然而,使用 5 枚 1 分或者 3 分的邮票根本不可能贴出 14 分的邮资。因此,对于这两种邮票的集合和上限 K=5,答案是 M=13。 [规模最大的一个点的时限是3s]小提示:因为14贴不出来,所以最高上限是13而不是15
这道题....思路和完全背包差不多  多了取邮票总数的范围..我的思路是用背包算出从1到K*a[n](最大面值邮票)每种值需要的最小邮票数  我的代码如下:
#include<bits/stdc++.h>
using namespace std;
int a[51]={0};
long long f[10000000];
int main()
{
 int K,n,m,s;
 scanf("%d%d",&K,&n);
  for(int i=1;i<=10000*K;i++)
   f[i]=233;
 for(int i=1;i<=n;i++)
  scanf("%d",&a[i]); 
 sort(a+1,a+1+n);
 f[0]=0;
 m=K*a[n];
 for(int i=1;i<=n;i++)
  for(int j=a[i];j<=m;j++)
      {f[j]=min(f[j],f[j-a[i]]+1);} 
 for(int i=1;i<=m;i++)
  if (f[i]>K) {cout<<i-1;return 0;}
 cout<<K*a[n];
 return 0;
}


然而一开始编的时候出现很多错误.....这个循环部分其实我的源代码是三重循环  我在第三重循环里考虑f[j-n*a[i]]的情况 ......加上一开始没有排序。3个TLE2个WA 加了SORT就是3个TLE  用自己的程序试TLE的点...整整花了10s  经过思考后我在三重循环里 加了一个if语句...还是要2秒多  限时1s  最后才发现最后一重循环是多余的  不加也没有影响  但玄学的是 RE了......给刘老师检查发现我犯了一个很滑稽的错误
 ....a数组开小了....只开了30个……(陷入俯卧撑)

第一个大瓶颈过了 马上又是第二大瓶颈(我是不是马上要渡劫了emmmmmm)

第三题1776 宝物筛选_NOI导刊2010提高(02)

题目描述终于,破解了千年的难题。小FF找到了王室的宝物室,里面堆满了无数价值连城的宝物……这下小FF可发财了,嘎嘎。但是这里的宝物实在是太多了,小FF的采集车似乎装不下那么多宝物。看来小FF只能含泪舍弃其中的一部分宝物了……小FF对洞穴里的宝物进行了整理,他发现每样宝物都有一件或者多件。他粗略估算了下每样宝物的价值,之后开始了宝物筛选工作:小FF有一个最大载重为W的采集车,洞穴里总共有n种宝物,每种宝物的价值为v[i],重量为w[i],每种宝物有m[i]件。小FF希望在采集车不超载的前提下,选择一些宝物装进采集车,使得它们的价值和最大

这是一个多重背包的问题  其实理解完完全背包  多重也不是那么难了 主要就是一个二进制的处理.虽然说他给的那串代码我并看不懂:
procedure MultiplePack(cost,weight,amount)
    if cost*amount>=V
        CompletePack(cost,weight)
        return
    integer k=1
    while k<amount
        ZeroOnePack(k*cost,k*weight)
        amount=amount-k
        k=k*2
    ZeroOnePack(amount*cost,amount*weight)

但是大概理解了拿来做题目还是没问题的.  先发最后AC的代码:
#include<bits/stdc++.h>
using namespace std;
int f[400010]={0}; 
int n,w,shu,k;
void zip(int value,int weight)
{
 for(int j=w;j>=weight;j--)
    f[j]=max(f[j],f[j-weight]+value);
}
struct baowu
{
 int weight,value,num;
}ba[500]; 
int main() 
{
 cin>>n>>w; 
 for(int i=1;i<=n;i++)
   scanf("%d%d%d",&ba[i].value,&ba[i].weight,&ba[i].num); 
 for(int i=1;i<=n;i++)
 {
  k=1;
  shu=ba[i].num-k;
  zip(ba[i].value,ba[i].weight);
  while (k<shu)
  {                         
   k=k*2;
   shu-=k;
   if (shu>=0)zip(k*ba[i].value,k*ba[i].weight); 
   else shu+=k; 
  }
  if (shu>0) zip(shu*ba[i].value,shu*ba[i].weight);
 }
 cout<<f[w]; 
 return 0;
} 
呃....这个问题  一开始编的时候出了很多错误  比如kX2是在调用前还是调用后啊  shu-k后大于小于0的问题 . 本来这个问题应该能顺利的过的  然而某次修改后  (在if(shu>=0)后面加else) 因为一些意外  需要点撤回  结果多按了以下把else都去掉了  然而我并没有发现  于是便陷入了8WA的噩梦......足足卡了有1个多小时....难受.


然后就是二维费用的背包问题了..理解还是比较好理解的  但是当我做

LUOGU1509 找啊找啊找GF

题目背景"找啊找啊找GF,找到一个好GF,吃顿饭啊拉拉手,你是我的好GF.再见.""诶,别再见啊..."七夕...七夕...七夕这个日子,对于sqybi这种单身的菜鸟来说是多么的痛苦...虽然他听着这首叫做"找啊找啊找GF"的歌,他还是很痛苦.为了避免这种痛苦,sqybi决定要给自己找点事情干.他去找到了七夕模拟赛的负责人zmc MM,让她给自己一个出题的任务.经过几天的死缠烂打,zmc MM终于同意了.但是,拿到这个任务的sqybi发现,原来出题比单身更让人感到无聊-_-....所以,他决定了,要在出题的同时去办另一件能够使自己不无聊的事情--给自己找GF.sqybi现在看中了n个MM,我们不妨把她们编号1到n.请MM吃饭是要花钱的,我们假设请i号MM吃饭要花rmb[i]块大洋.而希望骗MM当自己GF是要费人品的,我们假设请第i号MM吃饭试图让她当自己GF的行为(不妨称作泡该MM)要耗费rp[i]的人品.而对于每一个MM来说,sqybi都有一个对应的搞定她的时间,对于第i个MM来说叫做time[i]. sqybi保证自己有足够的魅力用time[i]的时间搞定第i个MM^_^.sqybi希望搞到尽量多的MM当自己的GF,这点是毋庸置疑的.但他不希望为此花费太多的时间(毕竟七夕赛的题目还没出),所以他希望在保证搞到MM数量最多的情况下花费的总时间最少.

很难受  二维费用理解了倒是好处理...加上一个时间最少  一开始看到蒙了  呃....感觉大体思路是对了  在舒大佬的提醒下  写了个程序的主体  但是比我之前的程序还要多WA了两个点  还在努力找问题中  下课了....
day2的效率比较水.....
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值