HDU 5693
在当前剩下的有序数组中选择X(X≥2)X(X≥2) 个连续数字;
1 看题目要注意后面几个字
要不就是删2 个要不就是删3个 3个以上可以由 2 3 组成 GGG
然后就是区间DP dp[i][j] 代表 从i 到 j 最多可以删除几个
然后呢 dp[i][j] = max ( dp[i][j], 1 w[i] 代表第i 个权值
1 如果 dp[i+1][j-1] == j-1 -(i+1) +1 &&w[i] w[j] 是等差 dp[i+1][j-1] +2
2 dp[i][k]+dp[k+1][r];
3 dp[i+1][k-1] +dp[k+1][j-1] 然后 w[i] w[k] w[j] 是等差 然后 dp[] [] dp[][] 要都是满的 反正都写上去就行了
#include<stdio.h> #include<algorithm> #include<stdlib.h> #include<cstring> #include<string> #include<cmath> #include<vector> #include<queue> #include<map> using namespace std; #define LL __int64 #define MAXN 310 #define inf 1000000000 int w[MAXN]; int d[MAXN]; int dp[MAXN][MAXN]; int vis[MAXN][MAXN]; int main() { int t; scanf("%d",&t); while(t--) { int n,m; scanf("%d%d",&n,&m); memset(dp,0,sizeof(dp)); memset(vis,0,sizeof(vis)); for(int i=1;i<=n;i++) scanf("%d",&w[i]); for(int i=1;i<=m;i++) scanf("%d",&d[i]); for(int i=1;i<=n;i++) { for(int j=i+1;j<=n;j++) { for(int k=1;k<=m;k++) { if(w[j]-w[i]==d[k]) vis[i][j]=1; } } } for(int len=1;len<=n;len++) { for(int l=1;l<=n;l++) { int r=l+len; if(r>n) break; dp[l][r]=max(dp[l][r-1],dp[l+1][r]); if(vis[l][r]&&dp[l+1][r-1]==r-l-1) dp[l][r]=max(dp[l][r],dp[l+1][r-1]+2); for(int i=l;i<r;i++) dp[l][r]=max(dp[l][i]+dp[i+1][r],dp[l][r]); for(int i=l+1;i<r;i++) { if(vis[l][i]&&dp[l+1][i-1]==i-l-1) dp[l][r]=max(dp[l][r],dp[l+1][i-1]+2+dp[i+1][r]); if(vis[i][r]&&dp[i+1][r-1]==r-i-1) dp[l][r]=max(dp[l][r],dp[l][i-1]+dp[i+1][r-1]+2); if(vis[l][i]&&vis[i][r]&&w[r]-w[i]==w[i]-w[l]&&dp[l+1][i-1]==i-l-1&&dp[i+1][r-1]==r-i-1) dp[l][r]=max(dp[l][r],r-l+1); } } } printf("%d ",dp[1][n]); } return 0; }
HDU 5694
要考虑对称 的情况 cnt[i] 代表这个串的长度 那么 这个整串 里肯定由 cnt[i-1]+1 个B 然而并没什么用
其实就是考虑 len <cnt[i] &&>cnt[i-1]的情况 那么 假设 len = 12
BB D BBDD B BBDD BDD
len
到中间的B 右边4 个和 左边 4 个 左边 4个取反后应该是对称的 那么 4 - 12 的 B 应该是 len -cnt[i-1]-1 加上中间的 就是 len-cnt[i-1]
然后再计算出长度为 cnt[i] - len的 递归一下
#include<stdio.h> #include<algorithm> #include<stdlib.h> #include<cstring> #include<string> #include<cmath> #include<vector> #include<queue> #include<map> using namespace std; #define ll __int64 #define MAXN 70 #define inf 1000000000 ll cnt[MAXN]; ll calc(ll x) { if(x==0) return 0; ll sum=0; for(int i=1;i<MAXN;i++) { if(cnt[i]==x) return cnt[i-1]+1; if(cnt[i]>x) { sum +=x-cnt[i-1]; return sum+calc(cnt[i]-x); } } } int main() { int t; scanf("%d",&t); cnt[1]=1; for(int i=2;i<MAXN;i++) cnt[i]=2*cnt[i-1]+1; while(t--) { ll l,r; scanf("%I64d%I64d",&l,&r); printf("%I64d ",calc(r)-calc(l-1)); } return 0; }