洛谷ios
暴力dp:
設\(f[i][j]\)表示考慮到了第\(i\)座城市用了\(j\)人的最大收益,枚舉在這個城市用多少人就能夠了。
優化:
發現用的人數必定是某個敵人的人數的二倍加一,那麼決策只有\(O(s)\)個。
時間複雜度\(O(snm)\)。(不滿)優化
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<vector> using namespace std; inline int read() { int x=0;bool t=false;char ch=getchar(); while((ch<'0'||ch>'9')&&ch!='-')ch=getchar(); if(ch=='-')t=true,ch=getchar(); while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar(); return t?-x:x; } int S,n,m,f[101][20020]; vector<int> A[105]; int main() { S=read();n=read();m=read(); for(int i=1;i<=S;++i) for(int j=1;j<=n;++j)A[j].push_back(read()); for(int i=1;i<=n;++i)sort(A[i].begin(),A[i].end()); memset(f,-63,sizeof(f));f[0][0]=0; for(int i=1,s=0;i<=n;++i) { int l=A[i].size()-1; for(int p=-1;p<=l&&2*A[i][p]+1<=m;++p) { int j=(~p)?2*A[i][p]+1:0; for(int k=0;k<=s&&k+j<=m;++k) f[i][j+k]=max(f[i][j+k],f[i-1][k]+i*(p+1)); } s+=A[i][l]*2+1; } int ans=0; for(int i=0;i<=m;++i)ans=max(ans,f[n][i]); printf("%d\n",ans); return 0; }