动态规划
Posted 冷暖知不知
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了动态规划相关的知识,希望对你有一定的参考价值。
int dp[1005][1005] = {0},len1,len2; char a[1005],b[1005]; void lcs() { for(int i = 1; i <= len1;i++) { for(int j = 1;j <= len2;j++) { if(a[i-1] == b[j-1]) dp[i][j] = dp[i-1][j-1]+1; else dp[i][j] = max(dp[i-1][j],dp[i][j-1]); } } } void printflcs(int x,int y) { if(x == 0 || y == 0) return; if(a[x-1] == b[y-1]) { printflcs(x-1,y-1); printf("%c",a[x-1]); } else if(dp[x][y-1] > dp[x-1][y]) printflcs(x,y-1); else printflcs(x-1,y); } int main() { scanf("%s%s",a,b); len1 = strlen(a); len2 = strlen(b); lcs(); printflcs(len1,len2); printf("\n"); return 0; }
int n,a[50005],b[50005] = {0}; int main() { scanf("%d",&n); for(int i = 1;i <= n;i++) scanf("%d",&a[i]); b[1] = a[1]; int len = 1; for(int i = 2;i <= n;i++) { int t = lower_bound(b+1,b+len+1,a[i])-b; b[t] = a[i]; if(t == len+1) len++; } printf("%d\n",len); return 0; }
int n,m,w[3500],v[3500],dp[13000] = {0}; //数量n,背包m,重量w,价值v int main() { scanf("%d%d",&n,&m); for(int i = 1;i <= n;i++) scanf("%d%d",&w[i],&v[i]); for(int i = 1;i <= n;i++) { for(int j = m;j >= w[i];j--) dp[j] = max(dp[j],dp[j-w[i]]+v[i]); } printf("%d\n",dp[m]); return 0; }
int dp[50005],v[1005],w[1005],n,W; //数量n,背包W,重量w,价值v //W很大,考虑每个价值的最小重量 int main() { ios::sync_with_stdio(0); while(cin >> n >> W) { memset(dp, 0x3f, sizeof(dp)); dp[0] = 0; int sum = 0; for(int i = 1;i <= n;i++) { cin >> w[i] >> v[i]; sum += v[i]; } for(int i = 1;i <= n;i++) { for(int j = sum;j >= v[i];j--) dp[j] = min(dp[j-v[i]]+w[i],dp[j]); } for(int i = sum;i >= 0;i--) { if(dp[i] <= W) { cout << i << endl; break; } } } return 0; }
int n,m,dp[105]; int main() { ios::sync_with_stdio(false); int T; cin >> T; while(T--) { memset(dp,0,sizeof(dp)); cin >> n >> m; for(int i = 1;i <= m;i++) { int p,h,c; //花费,价值,数量 cin >> p >> h >> c; int now = 1; while(1) { int t = min(now,c); c -= t; int pp = p*t,hh = h*t; for(int j = n;j >= pp;j--) dp[j] = max(dp[j],dp[j-pp]+hh); if(c == 0) break; } } cout << dp[n] << endl; } return 0; }
完全背包初始化分两种情况:
1、如果背包要求正好装满则初始化 dp[0] = 0, dp[1~m] = -INF。
2、如果不需要正好装满 dp[0~m] = 0。
int n,m,e,f,w[505],v[505],dp[10005]; //数量n,背包m,重量w,价值v int main() { int T; scanf("%d",&T); while(T--) { scanf("%d%d%d",&e,&f,&n); m = f-e; memset(dp,0x3f,sizeof(dp)); dp[0] = 0; for(int i = 1;i <= n;i++) scanf("%d%d",&v[i],&w[i]); for(int i = 1;i <= n;i++) { for(int j = w[i];j <= m;j++) dp[j] = min(dp[j],dp[j-w[i]]+v[i]); } if(dp[m] == INF) printf("This is impossible.\n"); else printf("The minimum amount of money in the piggy-bank is %d.\n",dp[m]); } return 0; } //HDU1114 完全背包
//不含62和4 int n,m,dp[15][5]; int a[15]; long long dfs(int now1,int now2,int limit) { if(now2 == 2) return 0; if(now1 == 0) return 1; if(!limit && dp[now1][now2] != -1) return dp[now1][now2]; int endd = limit?a[now1]:9,ans = 0; for(int i = 0;i <= endd;i++) { if(i == 4) continue; if(now2 == 1 && i == 2) ans += dfs(now1-1,2,limit && i == endd); else if(i == 6) ans += dfs(now1-1,1,limit && i == endd); else ans += dfs(now1-1,0,limit && i == endd); } if(!limit) dp[now1][now2] = ans; return ans; } int main() { memset(dp,-1,sizeof(dp)); while(cin >> n >> m && (n || m)) { n--; int cnt = 0; while(n) { a[++cnt] = n%10; n /= 10; } int ans = dfs(cnt,0,1); cnt = 0; while(m) { a[++cnt] = m%10; m /= 10; } cout << dfs(cnt,0,1)-ans << endl; } return 0; }
int a[15][15],sta[100],dp[15][100],sum[15][100],n,m; int main() { ios::sync_with_stdio(false); int T; cin >> T; while(T--) { memset(dp,0,sizeof(dp)); memset(sum,0,sizeof(sum)); cin >> n >> m; for(int i = 1;i <= n;i++) { for(int j = 1;j <= m;j++) cin >> a[i][j]; } int cnt = 0,endd = 1<<(m-1); for(int i = 0;i < endd;i++) { if(i & (i<<1)) continue; sta[++cnt] = i; } for(int i = 1;i < n;i++) { for(int j = 1;j <= cnt;j++) { for(int k = 1;k <= m-1;k++) { if(1<<(k-1) & sta[j]) { if(a[i][k] && a[i][k+1] && a[i+1][k] && a[i+1][k+1]) sum[i][j]++; } } } } for(int i = 1;i <= cnt;i++) dp[1][i] = sum[1][i]; for(int i = 1;i < n;i++) { for(int j = 1;j <= cnt;j++) { for(int k = 1;k <= cnt;k++) { dp[i+2][k] = max(dp[i+2][k],dp[i][j]+sum[i+2][k]); if(sta[j] & sta[k]) continue; if(sta[j] & (sta[k]<<1)) continue; if(sta[j] & (sta[k]>>1)) continue; dp[i+1][k] = max(dp[i+1][k],dp[i][j]+sum[i+1][k]); } } } int ans = 0; for(int i = 1;i <= cnt;i++) ans = max(ans,dp[n-1][i]); cout << ans << endl; } return 0; }
以上是关于动态规划的主要内容,如果未能解决你的问题,请参考以下文章