Codeforces Round #601 (Div. 2)E(寻找质因子,DP)
先分解质因数,对于当前a[i],假设当前的质因数为x,这个位置要满足能被k整除,有两个可能,要么是它向后一个转移x%k个,要么是后一个向它转移k-x%k个。
对于每一个a[i]满足后,因为只会对下一个位置产生影响,所以下一个位置a[i+1]算上a[i]产生的影响,之后又是一个新的子问题(禁止套娃)。
对于每一个质因数x,对所有所有位置i求min(a[i],x-a[i])的和,取所有质因子i的求和的最小值作为答案。
1 #define HAVE_STRUCT_TIMESPEC 2 #include<bits/stdc++.h> 3 using namespace std; 4 long long a[1000007]; 5 int main(){ 6 ios::sync_with_stdio(false); 7 cin.tie(NULL); 8 cout.tie(NULL); 9 long long n; 10 cin>>n; 11 long long sum=0; 12 for(long long i=1;i<=n;++i){ 13 cin>>a[i]; 14 sum+=a[i]; 15 } 16 if(sum<=1){ 17 cout<<-1; 18 return 0; 19 } 20 long long ans=1e18; 21 for(long long i=2;i*i<=sum;++i){ 22 long long flag=0; 23 while(sum%i==0){ 24 sum/=i; 25 flag=1; 26 } 27 if(flag){ 28 long long pre=0,summ=0; 29 for(long long j=1;j<=n;++j){ 30 pre=(a[j]+pre)%i; 31 summ+=min(pre,i-pre); 32 } 33 ans=min(ans,summ); 34 } 35 } 36 if(sum>1){ 37 long long pre=0,summ=0; 38 for(long long j=1;j<=n;++j){ 39 pre=(a[j]+pre)%sum; 40 summ+=min(pre,sum-pre); 41 } 42 ans=min(ans,summ); 43 } 44 cout<<ans; 45 return 0; 46 }
保持热爱 不懈努力
不试试看怎么知道会失败呢(划掉)
世上无难事 只要肯放弃(划掉)