地址:http://pan.baidu.com/s/1bneZgxp
T1:
经典区间dp,f[i][j]表示取i~j,那么f[i][j]=max{f[i+1][j]+v[i]*k,f[i][j-1]+v[j]*k};

1 #include<set> 2 #include<map> 3 #include<cmath> 4 #include<queue> 5 #include<vector> 6 #include<cstdio> 7 #include<cstdlib> 8 #include<cstring> 9 #include<iostream> 10 #include<algorithm> 11 using namespace std; 12 const int N = 2010; 13 #define For(i,n) for(int i=1;i<=n;i++) 14 #define Rep(i,l,r) for(int i=l;i<=r;i++) 15 #define Down(i,r,l) for(int i=r;i>=l;i--) 16 int n,v[N],f[N][N],Time,j; 17 void init(){ 18 freopen("trt.in","r",stdin); 19 freopen("trt.out","w",stdout); 20 scanf("%d",&n); 21 For(i,n) scanf("%d",&v[i]); 22 } 23 void dp(){ 24 For(k,n) 25 for(int i=1;i+k-1<=n;i++){ 26 behind=n-k+1; j=i+k-1; 27 f[i][j]=max(f[i][j],max(f[i+1][j]+Time*v[i],f[i][j-1]+Time*v[j])); 28 } 29 printf("%d ",f[1][n]); 30 } 31 int main(){ 32 init(); 33 dp(); 34 return 0; 35 }
T2:
爆搜即可,我加了二项式定理的剪枝

1 #include<set> 2 #include<map> 3 #include<cmath> 4 #include<queue> 5 #include<vector> 6 #include<cstdio> 7 #include<cstdlib> 8 #include<cstring> 9 #include<iostream> 10 #include<algorithm> 11 using namespace std; 12 const int N = 12; 13 #define For(i,n) for(int i=1;i<=n;i++) 14 #define Rep(i,l,r) for(int i=l;i<=r;i++) 15 #define Down(i,r,l) for(int i=r;i>=l;i--) 16 bool flag=false,used[N]; 17 int n,sum,A[N],C[N][N]; 18 19 void DFS(int k,int s){ 20 if(flag) return; 21 if(s>sum) return; 22 if(k==n+1){ 23 if(s==sum) flag=true; 24 return; 25 } 26 For(i,n) 27 if(!used[i]){ 28 A[k]=i;used[i]=true; 29 DFS(k+1,s+A[k]*C[n][k]); 30 if(flag) return; 31 used[i]=false; 32 } 33 } 34 35 int main(){ 36 freopen("bdsum.in","r",stdin); 37 freopen("bdsum.out","w",stdout); 38 C[1][1]=1; 39 Rep(i,2,10) 40 For(j,i) 41 C[i][j]=C[i-1][j]+C[i-1][j-1]; 42 scanf("%d%d",&n,&sum); 43 DFS(1,0); 44 For(i,n-1) printf("%d ",A[i]);printf("%d ",A[n]); 45 return 0; 46 }
T3:
二分枚举答案,只要枚举区间,用最大匹配检测即可

1 #include<set> 2 #include<map> 3 #include<cmath> 4 #include<queue> 5 #include<vector> 6 #include<cstdio> 7 #include<cstdlib> 8 #include<cstring> 9 #include<iostream> 10 #include<algorithm> 11 using namespace std; 12 const int N = 1010; 13 const int B = 24; 14 #define For(i,n) for(int i=1;i<=n;i++) 15 #define Rep(i,l,r) for(int i=l;i<=r;i++) 16 #define Down(i,r,l) for(int i=r;i>=l;i--) 17 18 int n,b,rank[N][N],contain[N],con[N][N]; 19 bool vis[N]; 20 21 void init(){ 22 scanf("%d%d",&n,&b); 23 For(i,n) 24 For(j,b) { 25 scanf("%d",&rank[i][j]);rank[i][rank[i][j]]=j;} 26 For(i,b) scanf("%d",&contain[i]); 27 } 28 29 bool dfs(int Left,int S,int Right){ 30 For(i,b) 31 if(Left<=rank[S][i]&&rank[S][i]<=Right) 32 if(!vis[i]){vis[i]=true; 33 For(j,contain[i]) 34 if(con[i][j]==-1){ 35 con[i][j]=S; 36 return true; 37 } 38 For(j,contain[i]) 39 if(dfs(Left,con[i][j],Right)){ 40 con[i][j]=S; 41 return true; 42 } 43 } 44 return false; 45 } 46 47 bool Check(int Dis){ 48 int ans=0; 49 For(Left,b-Dis+1){ 50 ans=0;memset(con,-1,sizeof(con)); 51 For(i,n){ 52 memset(vis,false,sizeof(vis)); 53 if(dfs(Left,i,Left+Dis-1)) ans++; 54 } 55 if(ans==n) return true; 56 } 57 return false; 58 } 59 60 void Work(){ 61 int Left=1,Right=b; 62 while(Right-Left>1){ 63 int Mid=(Left+Right)>>1; 64 if(Check(Mid)) Right=Mid; 65 else Left =Mid; 66 } 67 if(!Check(Left)) Left=Right; 68 printf("%d ",Left); 69 } 70 71 int main(){ 72 freopen("stead.in","r",stdin); 73 freopen("stead.out","w",stdout); 74 init(); 75 Work(); 76 return 0; 77 }