atcoder arc 122 a~b题Many FormulaeInsurance
Posted 要坚持写博客
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了atcoder arc 122 a~b题Many FormulaeInsurance相关的知识,希望对你有一定的参考价值。
A题链接
题目大意:不能存在两个及两个以上的减号,所有满足条件的式子之和。
题目思路:当时考试想到一半,就感觉编码能力不太会,然后就没做,
首先我们定义dp[N][2],这种选或不选的问题,一般都是这样定义的;
其中:dp[i][0]表示第i个为+,(这里我们可以把每个数看成是一个符号,自己在第一个数前面加了一个+。)因为这样看比较容易一点。
dp[i][1]表示第i个为-;当时就想到这里。但是没去写…………
这时候成功了一半了,然后我们还需要定义一个cnt[i][2]去记录数量,cnt[i][0]表示第i个数为+的数量,cnt[i][1]表示第i个数为-的数量。
此时我们可以写出dp式子了。
cnt[i][0]=cnt[i-1][0]+cnt[i-1][1];
cnt[i][1]=cnt[i][0];
dp[i][0]=dp[i-1][1]+dp[i-1][0]+cnt[i][0]*a[i];
dp[i][1]=dp[i-1][0]-cnt[i][1]*a[i];
最后的答案就是dp[n][0]+dp[n][1]了,
代码如下:
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<map>
#include<math.h>
#include<iostream>
#include<cmath>
#include<queue>
#include<vector>
#define IOS ios::sync_with_stdio(false);cin.tie();cout.tie(0)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pll;
const int N=1e5+10;
const int mod=1e9+7;
ll a[N];
ll dp[N][2],cnt[N][2];
int main()
{
IOS;
ll n;
cin>>n;
for(int i=1;i<=n;i++)
cin>>a[i];
dp[1][0]=a[1];
dp[1][1]=0;
cnt[1][0]=1;
cnt[1][1]=0;
for(int i=2;i<=n;i++)
{
cnt[i][0] = (cnt[i-1][0]%mod +cnt[i-1][1]%mod)%mod;
cnt[i][1] = cnt[i-1][0]%mod;
dp[i][0]=(dp[i-1][0]%mod+dp[i-1][1]%mod+cnt[i][0]*a[i]+mod)%mod;
dp[i][1]=(dp[i-1][0]%mod-cnt[i][1]*a[i]%mod+mod)%mod;
}
cout<<(dp[n][0]+dp[n][1])%mod<<endl;
return 0;
}
B题链接
题目大意,投资x元,亏了。对每个a[i]只会赔偿min(a[i],2x);
也就是最后题目给的那个式子:x+a[i]-min(a[i],2x);
求他亏钱最小,看案例一。
题目思路:从最后一个式子入手。这里我们排序之后对结果没有影响,但对我们的思路有利,就先排个序。排序之后我们枚举每一个a[i]的一半,都存在下面那个式子,这里为什么a[i]一半是对的呢?这里我们整体,如果后面那部分个数多,这里x肯定会是在a[i]/2a[i+1]/2之间取,我们最后肯定是后面那部分累加还有先低效前面x再减去x使得累计和最小。如果前面那部分多,我们最后是后面那部分累加之后再加上x,这里x肯定会是在a[i]/2a[i+1]/2之间取
代码如下:
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<map>
#include<math.h>
#include<iostream>
#include<cmath>
#include<queue>
#include<vector>
#define IOS ios::sync_with_stdio(false);cin.tie();cout.tie(0)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pll;
const int N=1e5+10;
const int mod=1e9+7;
double a[N],s[N];
int main()
{
IOS;
int n;
cin>>n;
double n1=n*1.0;
for(int i=1;i<=n;i++)
{
cin>>a[i];
}
sort(a+1,a+n+1);
for(int i=1;i<=n;i++)
{
s[i]=s[i-1]+a[i];
}
double sum=0x3f3f3f3f;//0x3f3f3f3f的十进制是1061109567,所以sum更新的时候就除以n1了,不然这数据范围满足不了
for(int i=1;i<=n;i++)
{
double w=a[i]/2;
double w1=(s[n]-s[i])-(n-i-i)*w;
sum=min(sum,w1/n1);
}
printf("%.6lf",sum);
return 0;
}
以上是关于atcoder arc 122 a~b题Many FormulaeInsurance的主要内容,如果未能解决你的问题,请参考以下文章