1.
P1796
代码:
#include<bits/stdc++.h>
using namespace std;
int n,T;
int dp[1000][1000];
int minn=1e9;
int main(){
cin>>T;
memset(dp,0x7f,sizeof(dp));
for(int i=0;i<=999;i++)dp[0][i]=0;
for(int i=1;i<=T;i++){
cin>>n;
for(int j=1;j<=n;j++){
int a,b;
while(cin>>a){
if(a==0)break;
cin>>b;
dp[i][j]=min(dp[i-1][a]+b,dp[i][j]);
}
if(i==T){
minn=min(minn,dp[i][j]);
}
}
//cout<<"EVA"<<endl;
}
cout<<minn;
return 0;
}
简单的dp
2.
P1806
代码:
#include<bits/stdc++.h>
using namespace std;
long long dp[1000][1000];
long long dfs(int lef,int pre){//保证
long long ans=1;
if(dp[lef][pre])return dp[lef][pre];
if(pre*2+3>lef)return 1;
for(int i=pre+1;i<=lef/2+1;i++)if(lef-i>i)ans+=dfs(lef-i,i);
dp[lef][pre]=ans;
return ans;
}
int n;
int main(){
cin>>n;
cout<<dfs(n,0)-1<<endl;
return 0;
}
暴力搜索加上记忆化
3.
P8742
我也是第一次遇见可行性dp,长见识了。
代码:
#include<bits/stdc++.h>
using namespace std;
int n,dp[101][100001],fa[101];
int main(){
cin>>n;
for(int i=1;i<=n;i++)cin>>fa[i];
dp[0][0]=1;
int ans=0;
for(int i=1;i<=n;i++){
for(int j=100000;j>=0;j--){
if(dp[i-1][j])dp[i][j]=1;
else if(dp[i-1][abs(j-fa[i])])dp[i][j]=1;
else if(dp[i-1][j+fa[i]])dp[i][j]=1;
else dp[i][j]=0;
}
if(i==n){
for(int j=1;j<=100000;j++)ans+=dp[i][j];
}
}
cout<<ans;
return 0;
}
4.
P1959
一道水体。
代码:
#include<bits/stdc++.h>
using namespace std;
int a[10000],b[10000];
int mapp[5010][5010];
bool pd(int x,int y){
if(x>=0 && x<=5000 && y>=0 && y<=5000){
return mapp[x][y];
}
else return 0;
}
int maxx=0;
int max(int x,int y){
return (x>y?x:y);
}
int main(){
int n;
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i]>>b[i];
mapp[a[i]][b[i]]=1;
}
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
bool flag=0;
if(i==j)continue;
int x=a[j]+b[i]-b[j];
int y=b[j]-a[i]+a[j];
int fx=a[i]+b[i]-b[j];
int fy=b[i]-a[i]+a[j];
if(pd(x,y) && pd(fx,fy))flag=1;
x=a[j]-b[i]+b[j];
y=b[j]+a[i]-a[j];
fx=a[i]-b[i]+b[j];
fy=b[i]+a[i]-a[j];
if(pd(x,y) && pd(fx,fy))flag=1;
if(flag)maxx=max(maxx,pow(a[i]-a[j],2)+pow(b[i]-b[j],2));
}
}
cout<<maxx;
return 0;
}
5.
P8794
思路:二分加上最短路秦颂搞定。,
#include<bits/stdc++.h>
using namespace std;
int mapp[1000][1000],low[1000][1000],ce[1000][1000];//初始组,低极限组,测试组
int n,P,dis[1000][1000];
bool pd(){
for(int k=1;k<=n;k++){
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if(ce[i][j]>ce[i][k]+ce[j][k]){
ce[i][j]=ce[j][i]=ce[i][k]+ce[j][k];
}
}
}
}
int ans=0;
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
ans+=ce[i][j];
}
}
return (ans<=P?1:0);
}
void change(int h){
int gong=(h/n);
h=h%n;
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
ce[i][j]=ce[j][i]=max(mapp[i][j]-gong,low[i][j]);
}
}
for(int i=1;i<=h;i++){
for(int j=1;j<=n;j++){
ce[i][j]=ce[j][i]=max(mapp[i][j]-1,low[i][j]);
}
}
}
int main(){
cin>>n>>P;
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
cin>>mapp[i][j];
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
cin>>low[i][j];
ce[i][j]=low[i][j];
}
}
if(!pd()){
cout<<"-1"<<endl;
return 0;
}
int l=0,r=100000;
while(l<=r-6){
int mid=(l+r)/2;
change(mid);
if(pd())r=mid;
else l=mid;
}
for(int i=l;i<=r;i++){
change(i);
if(pd()){
cout<<i<<endl;
return 0;
}
}
return 0;
}