Codefoeces的510D就是求几个数的最小公约数为零,并在这些最小公约数为零的情况中,
找出money最小的那种情况,输出money
因为li的最大值为10^9,所以最小公约数最大为10^9,
显然会爆内存,
所以要用到数据的离散化
这道题用了数据离散化<-新学的东西;然后还有扩展欧几里得<-上次比赛做到的题
然后学了一点别的
inline函数也就是所谓的内联函数可以用在调用频繁但是短小的函数里面
for example:
inline void toMin(int &a,int b)
{
if(a>b)
a=b;
return;
}
这样可以提高程序效率,同时增加可读性;
unique函数
函数lower_bound()在first和last的前闭后开区间进行二分查找,
返回大于或等于val第一个元素位置。如果所有元素都小于val,则返回last的位置
举例如下:
一个数组number序列为:4,10,11,30,69,70,96,100.设要插入数字3,9,111.pos为要插入的位置的下标
则
pos = lower_bound( number, number + 8, 3) - number,pos = 0.即number数组的下标为0的位置。
所以,要记住:函数lower_bound()在first和last中的前闭后开区间进行二分查找,返回大于或等于val的第一个元素位置。如果所有元素都小于val,则返回last的位置,且last的位置是越界的!!
Erase函数 擦除
http://blog.youkuaiyun.com/zhuimengzh/article/details/6841500
和unique函数配合使用可以去重
for example
value.erase(std::unique(value.begin(),value.end()),value.end());//对因子进行去重处理
还有gcd函数可以简单的写成
int gcd(int a,int b)
{
return b==0?a:gcd(b,a%b)
}
#include<cstdio>
#include<vector>
#include<algorithm>
using namespace std;
int num[305];
int price[305];
#define INF 0xfffffff
std::vector<int> value;
std::vector<int> dp;
inline void toMin(int &a,int b)
{
if(a>b)
a=b;
return;
}
int get(int a)
{
return std::lower_bound(value.begin(),value.end(),a)-value.begin();
}
int gcd(int a,int b)
{
return b==0?a:gcd(b,a%b);
}
void decompose(int n)
{
int i;
for(i=1;i*i<=n;i++){
if(n%i==0){
value.push_back(i);
value.push_back(n/i);//vector中存储了n的因子
}
}
return ;
}
int main()
{
int n,i;
scanf("%d",&n);
for(i=0;i<n;i++){
scanf("%d",&num[i]);
decompose(num[i]);
}
for(i=0;i<n;i++){
scanf("%d",&price[i]);
}
std::sort(value.begin(),value.end());
value.erase(std::unique(value.begin(),value.end()),value.end());//对因子进行去重处理
dp.resize(value.size(),INF);
for(i=0;i<n;i++){
int p=get(num[i]);
toMin(dp[p],price[i]);
for(int j=0;j<dp.size();j++){
if(dp[j]!=INF){
toMin(dp[get(gcd(value[j],num[i]))],price[i]+dp[j]);
}
}
}
int ans=dp[0];
if(ans==INF)
printf("-1\n");
else
printf("%d\n",ans);
return 0;
}
然后这套题是峰神和进爷教的表示很惶恐qwq
今天上游泳课..所以好累qwq 在泳池 的蓝色的水里世界是不一样的呢..有一种特别的感觉..
恍恍惚惚像是高三的夏天