既然选择了远方,便只顾风雨兼行|

H_W_Y

园龄:1年11个月粉丝:28关注:15

2023-07-18 16:52阅读: 14评论: 0推荐: 0

[P5228 [AHOI2013] 找硬币]题解-DP

20230718
传送门
发现ain都很小
也就是说我的面值最大是105
这样最大面值就可以用来做下标

其实最开始也不知道怎么做
我们现在考虑dp
dp[i]表示最大面值为i时的最小钱币数
由于ij一定是i的倍数
所以dp[ij]是可以从dp[i]转移过来
转移过程中
我可以把每一个价钱里所用的j个价值为i的钱币合并成为一个
类似倍增的一步一步逼近的思想
每一个ai中最多可以把ai/(ij)组钱币优化
这样统计总共有cnt组优化
那么dp[ij]=min(dp[ij],dp[i]cnt(j1))

时间复杂度为O(nmaxn)
关键就在于想到用dp来维护

#include <bits/stdc++.h>
using namespace std;

const int maxn=1e5;
int n,a[55],dp[maxn+5],ans=0,cnt=0;

int main(){
  /*2023.7.18 H_W_Y P5228 [AHOI2013] 找硬币 dp*/
  memset(dp,0x3f,sizeof(dp));dp[1]=0;
  scanf("%d",&n);
  for(int i=1;i<=n;i++) scanf("%d",&a[i]),dp[1]+=a[i];
  ans=dp[1];
  for(int i=1;i<=maxn/2;i++)
    for(int j=2;j*i<=maxn;j++){cnt=0;
      for(int k=1;k<=n;k++) cnt+=a[k]/(i*j);
      dp[i*j]=min(dp[i*j],dp[i]-cnt*(j-1));
      ans=min(ans,dp[i*j]);
	}
  printf("%d\n",ans);
  return 0;
}

本文作者:H_W_Y

本文链接:https://www.cnblogs.com/H-W-Y/p/17563464.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   H_W_Y  阅读(14)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起