NO.1 链条切割问题
NO.2 机器人两次走路
NO.3 租用游艇
NO.4 矩阵链乘
NO.5 石子合并-区间dp
NO.6 数字三角形
------自底向上计算—
//长度为n的链条进行切割
#include<bits/stdc++.h>
using namespace std;
const int N=10010;
const int minn=0x0c0c0c0c;
int a[N],n,r[N];
int main(){
cin>>n;
for(int i=1;i<=10;i++) cin>>a[i];
for(int i=11;i<=n;i++) a[i]=a[10];
for(int i=1;i<=n;i++){
for(int j=1;j<=i;j++){
r[i]=max(r[i],a[j]+r[i-j]);
}
}
cout<<r[n]<<endl;
return 0;
}
/*
13
1 5 8 9 10 17 17 20 24 30
*/
#include<bits/stdc++.h>
using namespace std;
int mp[101][101];
int dp[101][101][101][101],n,a,b,c;
void fun( int x1, int y1, int x2, int y2, int t){
if(x1==x2&&y1==y2)
dp[x1][y1][x2][y2]=max(dp[x1][y1][x2][y2],t+mp[x1][y1]);
else
dp[x1][y1][x2][y2]=max(dp[x1][y1][x2][y2],t+mp[x1][y1]+mp[x2][y2]);
}
int main(){
cin>>n;
while(cin>>a>>b>>c){
if(!a&&!b&&!c) break;
mp[a][b]=c;
}
//自底向上推导
dp[1][1][1][1]=mp[1][1];
for(int s=2;s<=2*n-1;s++){
for(int x1=1;x1<=s-1;x1++){
for(int x2=1;x2<=s-1;x2++){
int y1=s-x1;
int y2=s-x2;
int t=dp[x1][y1][x2][y2];
fun(x1+1,y1,x2+1,y2,t);
fun(x1+1,y1,x2,y2+1,t);
fun(x1,y1+1,x2+1,y2,t);
fun(x1,y1+1,x2,y2+1,t);
}
}
}
cout<<dp[n][n][n][n]<<endl;
return 0;
}
/*
8
2 3 13
2 6 6
3 5 7
4 4 14
5 2 21
5 6 4
6 3 15
7 2 14
0 0 0
*/
//租用游艇问题
#include<bits/stdc++.h>
using namespace std;
const int N=5010;
int n;
int a[N][N],dp[N];
//自底向上
int fun(){
for(int i=2;i<=n;i++){
dp[i]=a[1][i];
for(int j=2;j<i;j++){
dp[i]=min(dp[i],dp[j]+a[j][i]);
}
}
return dp[n];
}
int main(){
cin>>n;
for(int i=1;i<n;i++){
for(int j=i+1;j<=n;j++){
cin>>a[i][j];
}
}
cout<<fun()<<endl;
return 0;
}
/*
3
10 1
7
*/
bug一会再调–zhidaole ok
//注意的地方--在i-j循环中,第一层i从小到大,j要从i到小,为什么
//因为M[1][4]依赖于M[2][4],M[2][4]依赖于M[3][4]
#include<bits/stdc++.h>
using namespace std;
const int N=5050;
const int inf=0x3f3f3f3f;
int a[N],M[N][N],s[N][N],n,p;
void print(int i,int j){
if(i==j) cout<<"A"<<i;
else{
cout<<"(";
print(i,s[i][j]);
print(s[i][j]+1,j);
cout<<")";
}
}
int main(){
cin>>n;
//注意的地方--(n-1)个矩阵,记录n个值 i-i+1
for(int i=1;i<=n;i++){
cin>>a[i];
}
for(int i=1;i<=n-1;i++){
for(int j=i-1;j>=1;j--){
// for(int j=1;j<i;j++){ ×
M[j][i]=inf;
for(int k=j;k<i;k++){
int p=M[j][k]+M[k+1][i]+a[j]*a[k+1]*a[i+1];
if(p<M[j][i]){
M[j][i]=p;
s[j][i]=k;
}
}
}
}
cout<<M[1][n-1]<<endl;
print(1,n-1);
return 0;
}
/*
6
5 10 4 6 10 2
348
*/
#include<bits/stdc++.h>
using namespace std;
const int N=301;
const int inf=0x3f3f3f3f;
int a[N],n,s[N];
int dp[N][N];
int main(){
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i];
s[i]=s[i-1]+a[i];
}
//枚举长度
for(int len=1;len<n;len++){
for(int i=1;i+len<=n;i++){
int j=i+len;
dp[i][j]=inf;
for(int k=i;k<j;k++){
dp[i][j]=min(dp[i][j],dp[i][k]+dp[k+1][j]+s[j]-s[i-1]);
}
}
}
cout<<dp[1][n]<<endl;
return 0;
}
/*
4
1 3 5 2
*/
//自底向上
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=510;
int n;
int f[N][N];//从第i行j列走到最后一行的数字和
int w[N][N];//第i行j列的数值
int main(){
cin>>n;
//第n行有n个数
for(int i=1;i<=n;i++){
for(int j=1;j<=i;j++){
cin>>w[i][j];
}
}
for(int i=1;i<=n;i++) f[n][i]=w[n][i];
for(int i=n-1;i>0;i--){
for(int j=1;j<=i;j++){
f[i][j]=max(f[i+1][j],f[i+1][j+1])+w[i][j];
}
}
cout<<f[1][1]<<endl;
return 0;
}
/*
5
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5
*/