Educational Codeforces Round 126 (Rated for Div. 2)
很容易想到dp
dp[i,0]表示前i个 第i个不换 的最小值
dp[i,1]表示前i个 第i个换 的最小值
转移一下就行了
#include
using namespace std;
#define lowbit(x) x&(-x)
#define ll long long
const int maxn=30;
int n,T;
ll a[maxn],b[maxn],dp[maxn][2];
int main(){
cin>>T;
while(T--){
cin>>n;
memset(dp,0x7f,sizeof(dp));
for(int i=1;i<=n;i++)cin>>a[i];
for(int i=1;i<=n;i++)cin>>b[i];
dp[1][0]=dp[1][1]=0;
for(int i=2;i<=n;i++){
dp[i][0]=min(dp[i][0],abs(a[i]-a[i-1])+abs(b[i]-b[i-1])+dp[i-1][0]);
dp[i][0]=min(dp[i][0],abs(a[i]-b[i-1])+abs(b[i]-a[i-1])+dp[i-1][1]);
dp[i][1]=min(dp[i][1],abs(a[i]-a[i-1])+abs(b[i]-b[i-1])+dp[i-1][1]);
dp[i][1]=min(dp[i][1],abs(a[i]-b[i-1])+abs(b[i]-a[i-1])+dp[i-1][0]);
}
cout<
首先操作数肯定是不会超过15的 因为最多乘2的15次就是32768的倍数了
再考虑加的操作 要进行加操作的话 一定是先进行加 再进行乘
比如先加1再乘2 和先乘2再加1加1 都能到4 但是先加一定是更好的
所以枚举就好了
#include
using namespace std;
#define lowbit(x) x&(-x)
#define ll long long
int T;
int main(){
cin>>T;
while(T--){
int x,ans=1e9;cin>>x;
for(int i=0;i<=15;i++){
int now=x+i;
for(int j=0;j<=15;j++){
if(now%32768==0)
ans=min(ans,i+j);
now<<=1;
}
}
cout<
这个题目开始我想的是最大高度一定是数列中最高的那个 但其实不然
比如 1 1 1 变为2 2 2需要5 但是变为 3 3 3 只需要4(这是这个题目的关键)
所以最后的高度还可能是maxx+1 但是一定不能再高了 再高的话一定会额外付出
注意long long
剩下的是乱搞一下就好
#include
using namespace std;
#define lowbit(x) x&(-x)
#define ll long long
#define int ll
const int maxn=3e5+5;
int T;
int a[maxn];
signed main(){
cin>>T;
while(T--){
int n,x,maxx=0,ans=1e18;
cin>>n;
int cc=0;
for(int i=1;i<=n;i++)scanf("%d",&a[i]),maxx=max(maxx,a[i]);
while(cc<=1){
maxx+=cc;
int cnt1=0,cnt2=0;
for(int i=1;i<=n;i++)
cnt1+=(maxx-a[i])%2,cnt2+=(maxx-a[i])/2;
if(cnt1==cnt2)
ans=min(ans,cnt1+cnt2);
else if(cnt1>cnt2)
ans=min(ans,cnt2*2+(cnt1-cnt2)*2-1);
else if(cnt2>cnt1){
int lis=(cnt2-cnt1)*2/3;
int mod=(cnt2-cnt1)*2%3;
int jia;
if(mod==0)jia=0;
if(mod==1)jia=1;
if(mod==2)jia=2;
ans=min(ans,lis*2+cnt1*2+jia);
}
cc++;
}
cout<
贪心 考虑倒叙操作 依次满足最后一个 这样一定最优
剩下就是统计答案了 因为这个是递减的序列 所以我们只需要知道此时有多少个序列 用上个位置减的数减去此时序列个数
就是这个位置应该减的 问题就是有些序列结束了怎么办? 就在其开头位置标记一下就好了!!!这个操作是最重要的
#include
using namespace std;
#define lowbit(x) x&(-x)
#define ll long long
const int maxn=3e5+5;
ll n,k,ans;
ll a[maxn],edd[maxn];
int main(){
cin>>n>>k;
for(int i=1;i<=n;i++)cin>>a[i];
ll cnt=0,sum=0;
for(ll i=n;i>=1;i--){
sum-=cnt;
a[i]-=sum;
cnt-=edd[i];
if(a[i]<=0)continue;
ll res=min(k,i);
ll need=a[i]/res;
if(a[i]%res)need++;
ans+=need;
cnt+=need;
sum+=need*res;
if(i-res>=0)
edd[i-res]+=need;
}
cout<