3 条题解
-
0
你说得对,但我错解又过了
#include<bits/stdc++.h> using namespace std; typedef long long ll; int n,k,w[1000010],v[1000010]; ll g[50010]; vector<ll> vv[310],tot[310]; bool cmp(ll a,ll b){ return a>b; } int main(){ ios::sync_with_stdio(0); cin.tie(0); cin>>n>>k; int fl=1; for(int i=1;i<=n;i++){ cin>>w[i]>>v[i];fl&=w[i]==v[i]; } for(int i=1;i<=n;i++){ vv[w[i]].push_back(v[i]); } for(int i=1;i<=300;i++)if(vv[i].size()){ sort(vv[i].begin(),vv[i].end(),cmp); tot[i].push_back(0); tot[i].push_back(vv[i][0]); for(int j=1;j<vv[i].size();j++){ tot[i].push_back(tot[i].back()+vv[i][j]); } for(int j=0;j<i;j++){ int len=(k-j)/i+1; int l=j; while(l<=k)l+=i; l-=i; int now=l; for(;l>=j;l-=i){ if(now>l)now-=i; while((l-now)/i<tot[i].size()-1&&now>j&&g[now]+tot[i][(l-now)/i]<g[now-i]+tot[i][(l-(now-i))/i])now-=i; for(int p=now;p>=now-10*i&&p>=j&&(l-p)/i<tot[i].size();p-=i){ if(g[p]+tot[i][(l-p)/i]>g[now]+tot[i][(l-now)/i])now=p; g[l]=max(g[l],g[p]+tot[i][(l-p)/i]); } } } } for(int i=1;i<=k;i++)cout<<g[i]<<" "; return 0; } -
0
我还是第一次听说有分治 dp 这种东西(场上求出来个凸包觉得有滚木的作用)。
#include<bits/stdc++.h> using namespace std; #define int long long const int N=310,inf=0x3f3f3f3f3f3f3f3f; vector<int>c[N],sum,f,g; int dp[50010]; void dfs(int l,int r,int pl,int pr) { if(l>r)return; int mid=(l+r)>>1; int bl=max(pl,mid-(int)sum.size()+1),br=min(pr,mid),mx=-inf,id=bl; for(int i=bl;i<=br;i++) { int v=f[i]+sum[mid-i]; if(v>mx)mx=v,id=i; } g[mid]=mx; dfs(l,mid-1,pl,id); dfs(mid+1,r,id,pr); } signed main() { int n,m;cin>>n>>m; for(int i=1;i<=n;i++) { int x,y;cin>>x>>y; c[x].push_back(y); } memset(dp,-0x3f,sizeof(dp));dp[0]=0; for(int i=1;i<=300;i++) { if(c[i].empty())continue; sort(c[i].begin(),c[i].end(),[](int x,int y){return x>y;}); sum.clear();sum.resize(c[i].size()+1); for(int j=1;j<=c[i].size();j++)sum[j]=sum[j-1]+c[i][j-1]; for(int j=0;j<i;j++) { f.clear(); for(int k=j;k<=m;k+=i)f.push_back(dp[k]); int cnt=f.size()-1; g.assign(cnt+1,-inf); dfs(0,cnt,0,cnt); int id=0; for(int k=j;k<=m;k+=i)dp[k]=g[id++]; } } for(int i=1;i<=m;i++)dp[i]=max(dp[i],dp[i-1]); for(int i=1;i<=m;i++)cout<<dp[i]<<' ';cout<<'\n'; return 0; } -
0

#include<iostream> #include<cstdio> #include<algorithm> #include<vector> #define M 302 #define K 50002 #define N 1000002 using namespace std; typedef long long ll; ll dp[2][K],g[2][K]; int pre,now,pos,n,k,mx; vector<ll>vec[M]; inline int rd(){ int x=0;char c=getchar();bool f=0; while(!isdigit(c)){if(c=='-')f=1;c=getchar();} while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();} return f?-x:x; } inline ll cmp(ll x,ll y){return x>y;} void solve(int l,int r,int L,int R,int sum){ if(L>R||l>r)return; int mid=(L+R)>>1;ll num=0,point=-1; for(int i=max(mid-sum,l);i<=r&&i<mid;++i){ if(g[pre][i]+vec[pos][mid-i-1]>num){ num=g[pre][i]+vec[pos][mid-i-1];point=i; } } if(point<0)point=l; g[now][mid]=num; solve(l,point,L,mid-1,sum);solve(point,r,mid+1,R,sum); } int main(){ n=rd();k=rd();int x,y; for(int i=1;i<=n;++i){ x=rd();y=rd(); vec[x].push_back(y);mx=max(mx,x); } now=1;pre=0; for(int i=1;i<=mx;++i)if(vec[i].size()){ pos=i;swap(now,pre); sort(vec[i].begin(),vec[i].end(),cmp);int x=vec[i].size(); for(int j=1;j<x;++j)vec[i][j]+=vec[i][j-1]; for(int j=0;j<i;++j){ int p=0; for(int l=j;l<=k;l+=i,p++)g[pre][p]=dp[pre][l],g[now][p]=0;p--; solve(0,p,0,p,vec[i].size()); for(int l=j,p=0;l<=k;l+=i,p++)dp[now][l]=max(dp[now^1][l],g[now][p]); } } for(int i=1;i<=k;++i)printf("%lld ",dp[now][i]); return 0; }
- 1
信息
- ID
- 10097
- 时间
- 2000ms
- 内存
- 256MiB
- 难度
- 9
- 标签
- 递交数
- 28
- 已通过
- 3
- 上传者