我是靠谱客的博主 壮观高跟鞋,这篇文章主要介绍UVA10271_Chopsticks,现在分享给大家,希望可以做个参考。

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那么肯定不存在,不进行转移!!!!!!

则转移方程为

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#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[n][k]<<endl; } return 0; }



最后

以上就是壮观高跟鞋最近收集整理的关于UVA10271_Chopsticks的全部内容,更多相关UVA10271_Chopsticks内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(58)

评论列表共有 0 条评论

立即
投稿
返回
顶部