• HDU2697+DP


    Wa的版本。。。

    /*
    DP
    dp[i][j]:前i个取某些个且cost不超过j得到的最大价值
    */
    #include<stdio.h>
    #include<string.h>
    #include<stdlib.h>
    #include<algorithm>
    #include<iostream>
    #include<queue>
    #include<map>
    #include<stack>
    #include<set>
    #include<math.h>
    using namespace std;
    typedef long long int64;
    //typedef __int64 int64;
    typedef pair<int64,int64> PII;
    #define MP(a,b) make_pair((a),(b)) 
    const int maxn = 105;
    const int maxm = 10005;
    const int inf = 99999099;
    const double pi=acos(-1.0);
    const double eps = 1e-8;
    struct Node{
        int len;
        bool Choosed;
        int maxVal;
    }dp[ maxn ][ maxm ];
    void init(){
        for( int i=0;i<maxn;i++ ){
            for( int j=0;j<maxm;j++ ){
                dp[i][j].maxVal = 0;
                dp[i][j].len = 0;
                dp[i][j].Choosed = false;
            }
        }
    }
    int cost[ maxn ];
    int main(){
        int T;
        scanf("%d",&T);
        while( T-- ){
            int n,sum;
            scanf("%d%d",&n,&sum);
            //memset( dp,0,sizeof( dp ) );
            init();
            int SumCost = 0;
            int MinCost = inf;
            for( int i=0;i<n;i++ ){
                scanf("%d",&cost[i]);
                SumCost += cost[ i ];
                MinCost = min( MinCost,cost[i] );
            }
            if( MinCost>sum ) {
                printf("0
    ");
                continue;
            }
            if( MinCost==sum ) {
                printf("1
    ");
                continue;
            }
            if( sum>=SumCost ){
                printf("%d
    ",n*n);
                continue;
            }
            
            int ans = 0;
            for( int i=0;i<n;i++ ){
                for( int j=cost[i];j<=sum;j++ ){
                    dp[ i ][ j ].maxVal = 1;
                    dp[ i ][ j ].len = 1;
                    dp[ i ][ j ].Choosed = true;
                    ans = 1;
                }
            }//init of dp
            
            for( int i=1;i<n;i++ ){
                for( int j=0;j<=sum;j++ ){
                    if( dp[i-1][j].Choosed==false ){
                        if( j>=cost[i] ){
                            if( dp[i-1][j-cost[i]].maxVal+1>=dp[i-1][j].maxVal ){
                                dp[i][j].maxVal = dp[i-1][j-cost[i]].maxVal+1;
                                dp[i][j].len = 1;
                                dp[i][j].Choosed = true;
                            }
                            else {
                                if( dp[i-1][j].maxVal>dp[i][j].maxVal ){
                                    dp[i][j].maxVal = dp[i-1][j].maxVal;
                                    dp[i][j].len = 0;
                                    dp[i][j].Choosed = false;
                                }
                            }
                        }
                        else {
                            if( dp[i-1][j].maxVal>dp[i][j].maxVal ){
                                dp[i][j].maxVal = dp[i-1][j].maxVal;
                                dp[i][j].len = 0;
                                dp[i][j].Choosed = false;
                            }
                        }
                    }
                    else{
                        if( j>=cost[i] ){
                            if( dp[i-1][j-cost[i]].maxVal-dp[i-1][j-cost[i]].len*dp[i-1][j-cost[i]].len+(dp[i-1][j-cost[i]].len+1)*(dp[i-1][j-cost[i]].len+1)>=dp[i-1][j].maxVal ){
                                dp[i][j].maxVal = dp[i-1][j-cost[i]].maxVal-dp[i-1][j-cost[i]].len*dp[i-1][j-cost[i]].len+(dp[i-1][j-cost[i]].len+1)*(dp[i-1][j-cost[i]].len+1);
                                dp[i][j].len = dp[i-1][j-cost[i]].len+1;
                                dp[i][j].Choosed = true;
                            }
                            else{
                                if( dp[i-1][j].maxVal>dp[i][j].maxVal ){
                                    dp[i][j].maxVal = dp[i-1][j].maxVal;
                                    dp[i][j].len = 0;
                                    dp[i][j].Choosed = false;
                                }
                            }
                        }
                        else{
                            if( dp[i-1][j].maxVal>dp[i][j].maxVal ){
                                dp[i][j].maxVal = dp[i-1][j].maxVal;
                                dp[i][j].len = 0;
                                dp[i][j].Choosed = false;
                            }
                        }
                    }
                    ans = max(ans,dp[i][j].maxVal);
                    //printf("dp[%d][%d].val = %d, len = %d, choose = %d 
    ",i,j,dp[i][j].maxVal,dp[i][j].len,dp[i][j].Choosed);
                }
            }
            printf("%d
    ",ans);
        }
        return 0;
    }

    Ac代码。。

    dp[i][j]:前i个取某些个且cost不超过j得到的最大价值
    dp[ i ][ j ] 通过 1 到 i-1 之间的dp[ k ][ ? ] ( 1<=k<i ) 来更新。

    如果 dp[ i ][ j ]:取了第i个,则可能是被dp[ k ][ ? ]+ ??更新,反之则为dp[ i-1 ][ j ]

    /*
    DP
    */
    #include<stdio.h>
    #include<string.h>
    #include<stdlib.h>
    #include<algorithm>
    #include<iostream>
    #include<queue>
    #include<map>
    #include<stack>
    #include<set>
    #include<math.h>
    using namespace std;
    typedef long long int64;
    //typedef __int64 int64;
    typedef pair<int64,int64> PII;
    #define MP(a,b) make_pair((a),(b)) 
    const int maxn = 105;
    const int inf = 0x7fffffff;
    const double pi=acos(-1.0);
    const double eps = 1e-8;
    int dp[ maxn ][ maxn ];
    int a[ maxn ];
    int main(){
    	int T;
    	scanf("%d",&T);
    	while( T-- ){
    		int n,sum;
    		scanf("%d%d",&n,&sum);
    		int MinCost = inf;
    		for( int i=1;i<=n;i++ ){
    			scanf("%d",&a[i]);
    			if( a[i]<MinCost ) MinCost = a[i];
    		}
    		if( MinCost>sum ){
    			printf("0
    ");
    			continue;
    		}
    		if( MinCost==sum ){
    			puts("1");
    			continue;
    		}
    		int ans = 0;
    		memset( dp,0,sizeof( dp ) );
    		for( int i=1;i<=n;i++ ){
    			for( int j=0;j<=sum;j++ ){
    				int cnt = 0;
    				for( int k=1;k<=i;k++ ){
    					cnt += a[ i+1-k ];
    					if( cnt>j ) break;
    					dp[i][j] = max( dp[i][j],dp[i-k][j-cnt]+k*k );
    				}
    				dp[i][j] = max( dp[i][j],dp[i-1][j] );
    				ans = max( ans,dp[i][j] );
    			}
    		}
    		printf("%d
    ",ans);
    	}
    	return 0;
    }
    



  • 相关阅读:
    IOS开发学习 IDE环境搭建教程
    [转]CSS技巧:无懈可击的CSS圆角技术
    ASP.NET2.0 ObjectDataSource的使用详解(2) (转)
    ASP.NET 2.0 数据绑定概述(谭振林)
    分页储存过程
    ASP.NET2.0 ObjectDataSource的使用详解(1) (转)
    使用Gridview和ObjectDataSource轻松实现自定义分页
    FckEditor中文配置手册详细说明
    Head First IL中间语言实例深入经典诠释(转)
    C#的内存管理:堆栈、托管堆与指针 (转)
  • 原文地址:https://www.cnblogs.com/pangblog/p/3258274.html
Copyright © 2020-2023  润新知