hdu 4960 Another OCD Patient dp

news/2024/10/30 23:14:14/

题目链接:hdu 4960

题意:一排橡皮泥排成一排,要求最后捏成对称的,捏过的不能再捏.

思路:书读的少啊!!!看到题就想暴力,发现不行才想dp,状态转移方程dp[j]=min(dp[j],dp[i]+a[cnt]),初始化dp值为从开始捏到I.

代码:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <vector>
using namespace std;
#define MAXN 100010
#define INF 1e9
struct node{
int x,y;
node(){}
node(int xe,int ye):x(xe),y(ye) {}
};
int  data[MAXN],a[MAXN];
int n;
int dp[MAXN];
vector <node>  layer;
void init()
{
layer.clear();
for(int i=0;i<n;i++)
{
scanf("%d",&data[i]);
}
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
}
a[0]=0;
}
int be_layer()
{
int l=0,r=n-1,ans;
int x,y;
long long l_value,r_value;
x=1,y=1,l_value=data[0],r_value=data[n-1];
while(1)
{
if(l_value>r_value)
{
y++;
r--;
r_value+=data[r];
}
else if(l_value<r_value){
x++;
l++;
l_value+=data[l];
}
else {
// cout<<l<<" x "<<r<<endl;
if(l>=r)
{
//
ans=y;
break;
}
//cout<<l_value<<" "<<r_value<<endl;
//  printf("%d %d\n",x,y);
layer.push_back(node(x,y));
if(l+1==r)
{
ans=0;
break;
}
r--;
l++;
x=1,y=1,l_value=data[l],r_value=data[r];
}
}
return ans;
}
void slove()
{
int midcnt=be_layer();
//cout<<midcnt<<endl;
dp[0]=0;
int sizee=layer.size();
//cout<<midcnt<<" "<<sizee<<endl;
for(int i=0;i<sizee;i++)
// cout<<layer[i].x<<" "<<layer[i].y<<endl;
for(int i=1;i<=sizee;i++)
{
dp[i]=INF;
}
int sum_l=0,sum_r=0;
for(int j=0;j<sizee;j++)
{
sum_l+=layer[j].x;
sum_r+=layer[j].y;
dp[j]=(a[sum_l]+a[sum_r]);
}
for(int i=0;i<sizee;i++)
{
sum_l=0,sum_r=0;
for(int j=i+1;j<sizee;j++)
{
sum_l+=layer[j].x;
sum_r+=layer[j].y;
dp[j]=min(dp[j],dp[i]+a[sum_l]+a[sum_r]);
}
}
int ans=INF;
for(int i=sizee-1;i>=0;i--)
{
if(ans>dp[i]+a[midcnt])
{
ans=dp[i]+a[midcnt];
}
if(i)
{
midcnt+=(layer[i].x+layer[i].y);
}
}
if(sizee==0) ans=a[n];
printf("%d\n",ans);
}
int main()
{
//freopen("1001.in","r",stdin);
//freopen("data.out","w",stdout);
while(1){
scanf("%d",&n);
if(n==0) break;
init();
slove();
}
return 0;
}


http://www.ppmy.cn/news/460672.html

相关文章

HDU 4960(Another OCD Patient-区间dp)

Another OCD Patient Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others) Total Submission(s): 1320 Accepted Submission(s): 459 Problem Description 已知一个数列&#xff0c;现在把它分成k段&#xff0c;要求每段的和组成的新数列…

HDU 4960 (区间DP)

题目链接&#xff1a;点击这里 题意&#xff1a;把一个数列合并成回文序列&#xff0c;每一个数字只能和并一次&#xff0c;只能连续的子串进行合并&#xff0c;合并后的数字是他们的和&#xff0c;花费是他们中数字个数的函数。给出原始串和花费函数求最小的花费。 O(n) 扫一…

git版本管理入门(本地/远程仓库,常用命令)

目录 git简介 安装git 配置SSH key Linux环境下需要命令生成ssh key 本地git管理 多人协作流程 追加 重新提交 git命令 git commit本地和git push远程 git stash和git stash pop暂存 git status查看修改哪些了文件​ git diff 查看修改前后的差异 git log查看提交…

HDU 4960 Another OCD Patient

解题报告&#xff1a; 维护前缀和以及后缀和&#xff0c;相等则记录为断点 dp[ i ]表示断点 i 中间全部合并&#xff0c;两侧最优合并的最小代价 #include <algorithm> #include <iostream> #include <iomanip> #include <cstring> #include <cli…

【DP】 HDOJ 4960 Another OCD Patient

从两端往中间合并。。。合并过程中的数必然向数小的一方先合并。。。然后我们就可以这样先预处理出关节点。。。然后再关节点上一维DP即可。。。。 #include <iostream> #include <queue> #include <stack> #include <map> #include <set&g…

hdu 4960 Another OCD Patient(动态规划)

题目&#xff1a; Another OCD Patient Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others) Total Submission(s): 1320 Accepted Submission(s): 459 Problem Description Xiaoji is an OCD (obsessive-compulsive disorder) patie…

[dp]HDOJ4960 Another OCD Patient

题意: 给一个n, 第二行给n堆的价值v[i], 第三行给a[i]. a[i]表示把i堆合在一起需要的花费. 求把n堆变成类似回文的 需要的最小花费. 思路: ①记忆化搜索 比较好理解... dp[l][r] 记录l到r的最小花费 枚举对称轴 维护每次l到r之间对称 dp[l][r]min(dp[l][r], a[cur-l]a[r-i]df…

HDU 4960 Another OCD Patient 简单DP

思路&#xff1a; 因为是对称的&#xff0c;所以如果两段是对称的&#xff0c;那么一段的前缀和一定等于另一段的后缀和。根据这个性质&#xff0c;我们可以预处理出这个数列的对称点对。然后最后一个对称段是从哪里开始的&#xff0c;做n^2的DP就可以了。 代码&#xff1a; 1 …