zoukankan      html  css  js  c++  java
  • UOJ#311. 【UNR #2】积劳成疾 动态规划

    思路非常巧妙,令 $f[i][j]$ 表示前 $i$ 个数,最大值不大于 $j$ 的权和.

    转移的话枚举最大值出现的第一个位置,乘上该位置对应的贡献,然后发现最大值将 $1$ ~ $i$ 分成了两半.

    然后两个部分又是互不干扰的子问题,转移一下就行.

    把细节都提前考虑清楚后都不用怎么调.

    code: 

    #include <bits/stdc++.h>   
    #define N 409   
    #define ll long long 
    #define mod 998244353 
    #define setIO(s) freopen(s".in","r",stdin) 
    using namespace std; 
    int n,K; 
    int w[N],f[N][N];  
    int qpow(int x,int y) 
    {   
    	int tmp=1;  
    	for(;y;y>>=1,x=(ll)x*x%mod) if(y&1) tmp=(ll)tmp*x%mod;  
    	return tmp;  
    }
    int main() 
    { 
    	// setIO("input");      
    	scanf("%d%d",&n,&K);    
    	for(int i=1;i<=n;++i)  scanf("%d",&w[i]);     
    	for(int i=0;i<=n;++i)  f[0][i]=1;            
    	for(int i=1;i<K;++i) 
    	{
    		for(int j=1;j<=n;++j)
    		{
    			f[i][j]=f[i][j-1];  
    			for(int p=1;p<=i;++p)               
    				(f[i][j]+=(ll)f[p-1][j-1]*f[i-p][j]%mod)%=mod;   
    		}		
    	}    
    	for(int i=K;i<=n;++i) 
    	{
    		for(int j=1;j<=n;++j) 
    		{
    			f[i][j]=f[i][j-1];  
    			for(int p=1;p<=i;++p)  
    				(f[i][j]+=(ll)qpow(w[j],min(min(K,i-K+1),min(p,i-p+1)))*f[p-1][j-1]%mod*f[i-p][j]%mod)%=mod;   
    		}
    	}
    	printf("%d
    ",f[n][n]);            
    	return 0; 
    }
    

      

  • 相关阅读:
    本周总结
    本周总结
    本周总结
    本周总结
    性能分析(4)
    大型网站高性能架构
    第二天大数据清洗
    性能分析(2)
    六大质量属性——性能分析(1)
    java设计模式9-代理模式
  • 原文地址:https://www.cnblogs.com/guangheli/p/13072082.html
Copyright © 2011-2022 走看看