OI 笑传 #26

小清新 DP 回。解说会补的。

Luogu P14460

mx 的 NOIP 模拟 T1,赛时连猜带蒙结果 30min 切了(

code

Show me the code
#define rd read()
#define mkp make_pair
#define ls p<<1
#define rs p<<1|1
#define rep(i,a,b) for( int i=(a); i<=(b); ++i)
#define per(i,a,b) for( int i=(a); i>=(b); --i)
#include<bits/stdc++.h>
using namespace std;
typedef long long i64;
typedef unsigned long long u64;
typedef unsigned int u32;
typedef __int128 i128;
i64 read(){
  i64 x=0,f=1;
  char c=getchar();
  while(c>'9'||c<'0'){if(c=='-') f=-1;c=getchar();}
  while(c>='0'&&c<='9'){x=(x<<3)+(x<<1)+(c^48);c=getchar();}
  return x*f;
}
const int N=1e5+1145;
i64 dp[N];
i64 m,k,t1,t2;
i64 cst(int i,int j){
  if(j==-1||j==i)return LLONG_MAX;
  i64 tt=dp[j]+j*t2;
  i64 rem=i*k;
  if(tt<rem){
    return dp[j]+2*j*t2+(i-j)*t1+(rem-tt);
  }
  else {
    return dp[j]+2*j*t2+(i-j)*t1;
  }
}
int main(){
  
  int T;cin>>T;
  while(T--){
    cin>>m>>k>>t1>>t2;
    memset(dp,0x7f,sizeof dp);
    dp[0]=0;
    for(int i=1;i<=m;i++){
      int l=0,r=i-1;
      while(1){
        int mid=l+r>>1;
        i64 bk=cst(i,mid-1),cu=cst(i,mid),fw=cst(i,mid+1);
        if(bk>=cu&&cu<=fw){dp[i]=cu;break;}
        else if(bk<=cu&&cu<=fw)r=mid-1;
        else if(bk>=cu&&cu>=fw)l=mid+1;
      }
    }
    for(int i=1;i<=m;i++){
      if(i==m){cout<<dp[i];}
      else cout<<dp[i]<<' ';
    }
    cout<<'\n';
  }
  
  return 0;
}

CSP-X2025 山东 T4 勇者斗恶龙

小孩们的题,感觉挺有意思的。

code

Show me the code
#define rd read()
#define mkp make_pair
#define ls p<<1
#define rs p<<1|1
#define rep(i,a,b) for( int i=(a); i<=(b); ++i)
#define per(i,a,b) for( int i=(a); i>=(b); --i)
#include<bits/stdc++.h>
using namespace std;
typedef long long i64;
typedef unsigned long long u64;
typedef unsigned int u32;
typedef __int128 i128;
i64 read(){
  i64 x=0,f=1;
  char c=getchar();
  while(c>'9'||c<'0'){if(c=='-') f=-1;c=getchar();}
  while(c>='0'&&c<='9'){x=(x<<3)+(x<<1)+(c^48);c=getchar();}
  return x*f;
}
const int N=2e5+5;
i64 a[N],b[N];
i64 dp[N][5];
int main(){
  
  int n;cin>>n;
  for(int i=1;i<=n;i++){
    cin>>a[i]>>b[i];
  }
  for(int i=0;i<=N-3;i++){
    for(int j=0;j<=4;j++)dp[i][j]=1e18;
  }
  for(int i=0;i<=3;i++){
    dp[1][i]=b[1]*i;
  }
  for(int i=2;i<=n;i++){
    for(int j=0;j<=3;j++){
      for(int k=0;k<=3;k++){
        if(a[i-1]+j!=a[i]+k){
          dp[i][k]=min(dp[i][k],dp[i-1][j]+b[i]*k);
        }
      }
    }
  }
  i64 ans=1e18;
  for(int j=0;j<=3;j++){
    ans=min(ans,dp[n][j]);
  }
  cout<<ans;

  return 0;
}

CSP-J 2025 多边形

小孩们的题,感觉挺有意思的。虽然被卡了 30min。

code

Show me the code

CF2025D

code

Show me the code
#define rd read()
#define mkp make_pair
#define ls p<<1
#define rs p<<1|1
#define rep(i,a,b) for( int i=(a); i<=(b); ++i)
#define per(i,a,b) for( int i=(a); i>=(b); --i)
#include<bits/stdc++.h>
using namespace std;
typedef long long i64;
typedef unsigned long long u64;
typedef unsigned int u32;
typedef __int128 i128;
i64 read(){
  i64 x=0,f=1;
  char c=getchar();
  while(c>'9'||c<'0'){if(c=='-') f=-1;c=getchar();}
  while(c>='0'&&c<='9'){x=(x<<3)+(x<<1)+(c^48);c=getchar();}
  return x*f;
}
int dp[6000];
int d[6000];
int main(){
  
  int m,n;cin>>n>>m;
  int s=0;
  for(int i=1;i<=n;i++){
    int r;cin>>r;
    if(r==0){
      s++;
      for(int j=1;j<=s;j++){
        dp[j]=dp[j-1]+dp[j];
      }
      for(int j=s;j>=0;j--){
        if(j)dp[j]=max(dp[j],dp[j-1]);
      }
      for(int j=1;j<=s;j++){
        d[j]=dp[j]-dp[j-1];
      }
      for(int j=1;j<=s;j++){
        dp[j]=d[j];
      }
    }
    else if(r>0){
      dp[r]++;dp[s+1]--;
    }
    else if(r<0){
      r=-r;
      dp[0]++;dp[s-r+1]--;
    }
  }
  int deg=dp[0];
  for(int i=1;i<=m;i++){
    dp[i]=dp[i-1]+dp[i];
    deg=max(deg,dp[i]);
  }
  cout<<deg;
  
  return 0;
}

CF1038D

posted @ 2025-11-09 23:50  hm2ns  阅读(5)  评论(0)    收藏  举报