您的位置:首页 > 运维架构

UVA10271_Chopsticks

2015-09-10 02:36 453 查看
Chopsticks

大致就是有一堆筷子,知道了他们的长度,现在选长度为abc的三个筷子a<=b<=c为一对筷子,质量为(a-b)平方,现在选k双这样的筷子,求质量最小

思路:

第一次看到这个题目,人太弱完全没思路,因为之前状态转移都会有一个明显的子局面或者可以根据新增的i+1变量就行状态转移,可是这一题,一直想不出来如何转移,以为新增的筷子可以是a或b或c,但后面看了题解之后发现,人弱能怪谁!!!这题在最开始状态就很模糊没有建好,而且转移的时候还有技巧

应该这样建dp[i][k]就是前i个筷子组成k双筷子,那么为了方便状态的转移并且使用贪心可以先sort一下从大到小排,并且设定选取筷子的时候默认是再选a,同时他的前一个就是b,这样c只要位于b的前面就行了,c对质量无影响.那么问题来了,万一这样选不存在c了怎么办,所以转移的时候如果j<i*3那么肯定不存在,不进行转移!!!!!!

则转移方程为

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<string>
#include<queue>
#include<cstdlib>
#include<algorithm>
#include<stack>
#include<map>
#include<queue>
#include<vector>
using namespace std;
const int maxn = 5e3+100;
const int INF = 0x3f3f3f3f;
int a[maxn],dp[maxn][maxn];
int main(){
#ifdef LOCAL
    freopen("in.txt","r",stdin);
   // freopen("out.txt","w",stdout);
 #endif
    int t,n,k;
    cin>>t;
    while(t--){
        cin>>k>>n;k+=8;
        for(int i=n;i>0;--i) cin>>a[i];
        for(int i=1;i<=n;i++){
            dp[i][0]=0;
            for(int j=1;j<=k;j++){
                dp[i][j]=INF;
            }
        }
        for(int i=3;i<=n;i++){
            for(int j=1;j<=k;j++){
                if(i>=j*3&&dp[i-2][j-1]!=INF){
                    dp[i][j]=min(dp[i-1][j],dp[i-2][j-1]+(a[i]-a[i-1])*(a[i]-a[i-1]));
                }
            }
        }
        cout<<dp
[k]<<endl;

    }
    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: