• 四边形不等式求解合并石子(菜鸡做法)


    这里暂时先只提供min的做法,求max的时候直接把值改成负数即可
    dp:
    f[i][j]=f[i][k]+f[k+1][j]+d[j]-d[i-1];

    正常代码:

    #include<bits/stdc++.h>
    #define ll long long
    #define maxn 402
    
    using namespace std;
    
    ll n,a[maxn];
    ll f[maxn][maxn];
    ll d[maxn];
    
    
    int main(){
    	cin>>n;
    	for(int i=1;i<=n;i++) cin>>a[i],a[i+n]=a[i];
    	memset(f,0x3f,sizeof(f));
    	for(int i=1;i<=2*n;i++)
    	{
    		d[i]=d[i-1]+a[i];
    		f[i][i]=0;
    	
    	}
    	
    	
    	
    	
    	for(int l=2;l<=n;l++){
    		for(int i=1;i<=2*n-l+1;i++){
    			int j=i+l-1;
    			for(int k=i;k<j;k++){
    //				cout<<f[i][]
    				if(f[i][j]>f[i][k]+f[k+1][j]+d[j]-d[i-1]){
    					cout<<k<<" ";
    					f[i][j]=f[i][k]+f[k+1][j]+d[j]-d[i-1];
    //					cout<<"jnvadl
    ";
    				}
    				
    			}cout<<'
    ';
    			
    		}
    	}
    	
    	ll ans=99999999;
    	for(int i=1;i<=n;i++){
    		ans=min(ans,f[i][i+n-1]);
    	}
    	
    	cout<<ans<<'
    ';
    	return 0;
    }
    

    如果想用四边形不等式来做,那么我们先判断这个式子是不是符合四边形不等式的条件,发现和模板长得好像差不多~~

    我们接着枚举断点k,看一看是不是有单调性:

    #include<bits/stdc++.h>
    #define ll long long
    #define maxn 402
    
    using namespace std;
    
    ll n,a[maxn];
    ll f[maxn][maxn];
    ll d[maxn];
    
    
    int main(){
    	cin>>n;
    	for(int i=1;i<=n;i++) cin>>a[i],a[i+n]=a[i];
    	memset(f,0x3f,sizeof(f));
    	for(int i=1;i<=2*n;i++)
    	{
    		d[i]=d[i-1]+a[i];
    		f[i][i]=0;
    	
    	}
    	
    	
    	
    	
    	for(int l=2;l<=n;l++){
    		for(int i=1;i<=2*n-l+1;i++){
    			int j=i+l-1;
    			for(int k=i;k<j;k++){
    //				cout<<f[i][]
    				if(f[i][j]>f[i][k]+f[k+1][j]+d[j]-d[i-1]){
    					cout<<k<<" ";
    					f[i][j]=f[i][k]+f[k+1][j]+d[j]-d[i-1];
    //					cout<<"jnvadl
    ";
    				}
    				
    			}cout<<'
    ';
    			
    		}
    	}
    	
    	ll ans=99999999;
    	for(int i=1;i<=n;i++){
    		ans=min(ans,f[i][i+n-1]);
    	}
    	
    	cout<<ans<<'
    ';
    	return 0;
    }
    

    结果:

    4
    4 5 9 4
    1
    2
    3
    4
    5
    6
    7
    1 2
    2
    3
    4 5
    5 6
    6
    1 2
    2 3
    3
    4 5 6
    5 6
    43
    

    发现的确是有单调性的,所以我们的dp也有很大可能具有单调性

    两个都试一下:
    第一个;
    f[i+1][j]<=s[i][j]<=f[i][j-1]
    i正序枚举:

    #include<bits/stdc++.h>
    #define ll long long
    #define maxn 402
    
    using namespace std;
    
    ll n,a[maxn];
    ll f[maxn][maxn];
    ll d[maxn],s[maxn][maxn];
    
    
    int main(){
    	cin>>n;
    	for(int i=1;i<=n;i++) cin>>a[i],a[i+n]=a[i],s[i][i]=i,s[i+n][i+n]=i+n;
    	memset(f,0x3f,sizeof(f));
    	for(int i=1;i<=2*n;i++)
    	{
    		d[i]=d[i-1]+a[i];
    		f[i][i]=0;
    	
    	}
    	
    	
    	
    	
    	/*for(int l=2;l<=n;l++){
    		for(int i=1;i<=2*n-l+1;i++){
    			int j=i+l-1;
    			for(int k=i;k<j;k++){
    //				cout<<f[i][]
    				if(f[i][j]>f[i][k]+f[k+1][j]+d[j]-d[i-1]){
    					cout<<k<<" ";
    					f[i][j]=f[i][k]+f[k+1][j]+d[j]-d[i-1];
    //					cout<<"jnvadl
    ";
    				}
    				
    			}cout<<'
    ';
    			
    		}
    	}*/
    	
    	for(int i=1;i<=2*n;i++) 
    		for(int j=i+1;j<=2*n;j++){
    			ll tmp=0x3f3f3f3f3f,p;
    			for(int k=s[i+1][j];k<=s[i][j-1];k++){
    				if(tmp>f[i][k]+f[k+1][j]+d[j]-d[i-1]){
    					tmp=f[i][k]+f[k+1][j]+d[j]-d[i-1];
    					p=k;
    				}
    			}
    			f[i][j]=tmp;
    			s[i][j]=p;//决策点 
    		}
    	
    	
    	ll ans=99999999;
    	for(int i=1;i<=n;i++){
    		ans=min(ans,f[i][i+n-1]);
    	}
    	
    	cout<<ans<<'
    ';
    	return 0;
    }
    

    结果错误~~

    i倒序枚举;

    #include<bits/stdc++.h>
    #define ll long long
    #define maxn 402
    
    using namespace std;
    
    ll n,a[maxn];
    ll f[maxn][maxn];
    ll d[maxn],s[maxn][maxn];
    
    
    int main(){
    	cin>>n;
    	for(int i=1;i<=n;i++) cin>>a[i],a[i+n]=a[i],s[i][i]=i,s[i+n][i+n]=i+n;
    	memset(f,0x3f,sizeof(f));
    	for(int i=1;i<=2*n;i++)
    	{
    		d[i]=d[i-1]+a[i];
    		f[i][i]=0;
    	
    	}
    	
    	
    	
    	
    	/*for(int l=2;l<=n;l++){
    		for(int i=1;i<=2*n-l+1;i++){
    			int j=i+l-1;
    			for(int k=i;k<j;k++){
    //				cout<<f[i][]
    				if(f[i][j]>f[i][k]+f[k+1][j]+d[j]-d[i-1]){
    					cout<<k<<" ";
    					f[i][j]=f[i][k]+f[k+1][j]+d[j]-d[i-1];
    //					cout<<"jnvadl
    ";
    				}
    				
    			}cout<<'
    ';
    			
    		}
    	}*/
    	
    	for(int i=n*2;i>=1;i--)//倒叙 
    		for(int j=i+1;j<=2*n;j++){
    			ll tmp=0x3f3f3f3f3f,p;
    			for(int k=s[i+1][j];k<=s[i][j-1];k++){
    				if(tmp>f[i][k]+f[k+1][j]+d[j]-d[i-1]){
    					tmp=f[i][k]+f[k+1][j]+d[j]-d[i-1];
    					p=k;
    				}
    			}
    			f[i][j]=tmp;
    			s[i][j]=p;//决策点 
    		}
    	
    	
    	ll ans=99999999;
    	for(int i=1;i<=n;i++){
    		ans=min(ans,f[i][i+n-1]);
    	}
    	
    	cout<<ans<<'
    ';
    	return 0;
    }
    
    

    结果错误~~

    试一试第二种:
    s[i][j-1]<=s[i][j]<=s[i+1][j]

    i正序:

    
    #include<bits/stdc++.h>
    #define ll long long
    #define maxn 402
    
    using namespace std;
    
    ll n,a[maxn];
    ll f[maxn][maxn];
    ll d[maxn],s[maxn][maxn];
    
    
    int main(){
    	cin>>n;
    	for(int i=1;i<=n;i++) cin>>a[i],a[i+n]=a[i],s[i][i]=i,s[i+n][i+n]=i+n;
    	memset(f,0x3f,sizeof(f));
    	for(int i=1;i<=2*n;i++)
    	{
    		d[i]=d[i-1]+a[i];
    		f[i][i]=0;
    	
    	}
    	
    	
    	
    	
    	/*for(int l=2;l<=n;l++){
    		for(int i=1;i<=2*n-l+1;i++){
    			int j=i+l-1;
    			for(int k=i;k<j;k++){
    //				cout<<f[i][]
    				if(f[i][j]>f[i][k]+f[k+1][j]+d[j]-d[i-1]){
    					cout<<k<<" ";
    					f[i][j]=f[i][k]+f[k+1][j]+d[j]-d[i-1];
    //					cout<<"jnvadl
    ";
    				}
    				
    			}cout<<'
    ';
    			
    		}
    	}*/
    	
    	for(int i=1;i<=2*n;i++)
    		for(int j=i+1;j<=2*n;j++){
    			ll tmp=0x3f3f3f3f3f,p;
    			for(int k=s[i][j-1];k<=s[i+1][j];k++){
    				if(tmp>f[i][k]+f[k+1][j]+d[j]-d[i-1]){
    					tmp=f[i][k]+f[k+1][j]+d[j]-d[i-1];
    					p=k;
    				}
    			}
    			f[i][j]=tmp;
    			s[i][j]=p;//决策点 
    		}
    	
    	
    	ll ans=99999999;
    	for(int i=1;i<=n;i++){
    		ans=min(ans,f[i][i+n-1]);
    	}
    	
    	cout<<ans<<'
    ';
    	return 0;
    }
    
    

    结果错误

    倒序:

    
    #include<bits/stdc++.h>
    #define ll long long
    #define maxn 402
    
    using namespace std;
    
    ll n,a[maxn];
    ll f[maxn][maxn];
    ll d[maxn],s[maxn][maxn];
    
    
    int main(){
    	cin>>n;
    	for(int i=1;i<=n;i++) cin>>a[i],a[i+n]=a[i],s[i][i]=i,s[i+n][i+n]=i+n;
    	memset(f,0x3f,sizeof(f));
    	for(int i=1;i<=2*n;i++)
    	{
    		d[i]=d[i-1]+a[i];
    		f[i][i]=0;
    	
    	}
    	
    	
    	
    	
    	/*for(int l=2;l<=n;l++){
    		for(int i=1;i<=2*n-l+1;i++){
    			int j=i+l-1;
    			for(int k=i;k<j;k++){
    //				cout<<f[i][]
    				if(f[i][j]>f[i][k]+f[k+1][j]+d[j]-d[i-1]){
    					cout<<k<<" ";
    					f[i][j]=f[i][k]+f[k+1][j]+d[j]-d[i-1];
    //					cout<<"jnvadl
    ";
    				}
    				
    			}cout<<'
    ';
    			
    		}
    	}*/
    	
    	for(int i=n*2;i>=1;i--)//倒叙 
    		for(int j=i+1;j<=2*n;j++){
    			ll tmp=0x3f3f3f3f3f,p;
    			for(int k=s[i][j-1];k<=s[i+1][j];k++){
    				if(tmp>f[i][k]+f[k+1][j]+d[j]-d[i-1]){
    					tmp=f[i][k]+f[k+1][j]+d[j]-d[i-1];
    					p=k;
    				}
    			}
    			f[i][j]=tmp;
    			s[i][j]=p;//决策点 
    		}
    	
    	
    	ll ans=99999999;
    	for(int i=1;i<=n;i++){
    		ans=min(ans,f[i][i+n-1]);
    	}
    	
    	cout<<ans<<'
    ';
    	return 0;
    }
    

    结果正确!!

    综上:四边形不等式很简单,多试几次就好啦~~()

  • 相关阅读:
    第15.14节 PyQt(Python+Qt)入门学习:Designer的Buttons按钮详解
    PyQt(Python+Qt)学习随笔:Designer中的QDialogButtonBox的orientation和centerButtons属性
    PyQt(Python+Qt)学习随笔:Designer中的QDialogButtonBox的按钮改变缺省文字的方法
    PyQt(Python+Qt)学习随笔:Designer中的QDialogButtonBox增加自定义按钮的方法
    PyQt(Python+Qt)学习随笔:Designer中QDialogButtonBox确认clicked信号是哪个按钮发送的方法
    织梦更新列表页提示Fatal error: Call to a member function GetInnerText() on a non-object 解决方法
    怎么调取dede三级栏目名及栏目下的内容列表
    DEDE [field:global name=autoindex/] 按序列号递增
    在cms以及kindeditor中插入百度动态地图的方法
    DEDE文章列表加上序号效果
  • 原文地址:https://www.cnblogs.com/yxr001002/p/14544782.html
Copyright © 2020-2023  润新知