2017.9.13 找硬币 失败总结
来源:互联网 发布:网络棋牌赌博举报没用 编辑:程序博客网 时间:2024/06/06 15:54
做过一大波玄学的搜索剪枝,然后一看n<=50,就想dfs了
然而并不会dfs,剪枝过于玄学,而且似乎不好用
于是弃疗看题解
然后就发现自己zz了
其实本来是知道如果知道最后一个数,就只用枚举最后一个数的倍数就行了
但怎么就没想到dp呢,这dp其实是比较明显的约数dp、
因为3*4一定不会比3*2*2更优,所以直接每次都乘素数去试
用所有约数去更新倍数就好,
那序列前面的数都不知道,怎么知道每个数被前面的数试过之后剩下多少?
这里需要确定,接写来试的都是这个数的倍数,所以剩下的这些数就必须是这个数的倍数,才能保证正确性
状态需要设计的满足递推性而不一定直观
所以直接f【i】表示不用i,用i的约数填满不是i的倍数的方案数;←神(gui)奇(yi)
dp即可、
码:
#include<iostream>#include<cstdio>using namespace std;#define inf 1000000007#define N 55#define M 100005int a[N],su[M],f[M],tot,ans,n,m;bool he[M];int work(int x,int y){int ans=0,i;for(i=1;i<=n;i++)ans+=a[i]%y/x;return ans;}int main(){int i,j;scanf("%d",&n);for(i=1;i<=n;i++){scanf("%d",&a[i]);m=max(m,a[i]);}for(i=2;i<=m;i++){if(!he[i]){su[++tot]=i;}for(j=1;j<=tot&&su[j]*i<=tot;j++){he[i*su[j]]=1;if(i%su[j]==0)break;}} for(i=2;i<=m;i++)f[i]=inf; ans=inf;for(i=1;i<=m;i++){ans=min(ans,f[i]+work(i,inf));for(j=1;j<=tot&&i*su[j]<=m;j++){int k=i*su[j];f[k]=min(f[k],f[i]+work(i,k));}}printf("%d",ans);}
阅读全文
0 0
- 2017.9.13 找硬币 失败总结
- 2017.9.7 翻硬币 失败总结
- 找硬币
- 2017.10.23 硬币购物 失败总结
- 找硬币问题
- 贪心算法-找硬币
- 找硬币问题
- 找换硬币问题
- 找硬币问题
- 找硬币问题
- 最少找硬币问题
- bzoj3233 [Ahoi2013]找硬币
- 【算法题】找硬币
- DFS 找硬币
- 3233: [Ahoi2013]找硬币
- 【DP】【cofun1900】找硬币
- 2017.10.9 找相同字符 失败总结
- 找重量不一样的硬币
- Swift之类与结构体
- PAT 1003. 我要通过!(20)
- 0912 Oracle函数
- 【cuda】This graphics driver could not find compatible graphics hardware..
- 关于ppp、PPPoE、PPTP、L2TP、IPSec协议的简单认识
- 2017.9.13 找硬币 失败总结
- echart柱形图上面显示内容
- CodeForces 493 E.Vasya and Polynomial(数学)
- Spark连接MongDB
- The Little Schemer读书笔记1
- 最大值以及下标和最小值以及下标js
- 17年9月Java软件工程师面试第四站
- Pyramid match kernel and spatial pyramid matching
- ubuntu的网络设置